<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 6.3.0">
  <link rel="apple-touch-icon" sizes="180x180" href="/images/favicon.ico">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon.ico">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon.ico">
  <link rel="mask-icon" href="/images/favicon.ico" color="#222">

<link rel="stylesheet" href="/css/main.css">


<link rel="stylesheet" href="/lib/font-awesome/css/all.min.css">
  <link rel="stylesheet" href="//cdn.jsdelivr.net/gh/fancyapps/fancybox@3/dist/jquery.fancybox.min.css">

<script id="hexo-configurations">
    var NexT = window.NexT || {};
    var CONFIG = {"hostname":"daorongxing.gitee.io","root":"/","scheme":"Gemini","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":true,"style":"mac"},"back2top":{"enable":true,"sidebar":true,"scrollpercent":true},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":true,"mediumzoom":false,"lazyload":false,"pangu":true,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":true,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},"path":"search.xml"};
  </script>

  <meta name="description" content="Spring_day01今日目标   掌握Spring相关概念 完成IOC&#x2F;DI的入门案例编写 掌握IOC的相关配置与使用 掌握DI的相关配置与使用   1，课程介绍对于一门新技术，我们需要从为什么要学、学什么以及怎么学这三个方向入手来学习。那对于Spring来说: 1.1 为什么要学? 从使用和占有率看  Spring在市场的占有率与使用率高  Spring在企业的技术选型命中率高">
<meta property="og:type" content="article">
<meta property="og:title" content="Spring_1">
<meta property="og:url" content="https://daorongxing.gitee.io/post/3701/index.html">
<meta property="og:site_name" content="邢道荣的个人博客">
<meta property="og:description" content="Spring_day01今日目标   掌握Spring相关概念 完成IOC&#x2F;DI的入门案例编写 掌握IOC的相关配置与使用 掌握DI的相关配置与使用   1，课程介绍对于一门新技术，我们需要从为什么要学、学什么以及怎么学这三个方向入手来学习。那对于Spring来说: 1.1 为什么要学? 从使用和占有率看  Spring在市场的占有率与使用率高  Spring在企业的技术选型命中率高">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://daorongxing.gitee.io/images/image-20210729171139088.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/image-20210729171850181.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629714811435.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/image-20210729171926576.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/image-20210729172153796.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629720945720.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629722300996.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629723232339.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629724206002.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629735078619.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629734010072.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629734336440.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/image-20210729184337603.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629736314989.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/image-20210729184337603.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/image-20210729183500978.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629769227068.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/image-20210729183558051.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/image-20210729184337603.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629771744003.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629771880920.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629771972886.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/image-20210729183628138.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629772538893.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629772538893.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629772928714.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1631529887695.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629775585694.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629775972507.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629775972507.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629776331499.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629786862329.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/image-20210729195248948.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629786862329.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629788036885.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629788769436.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/image-20210729200203249.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629788769436.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629788769436.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629790070607.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629790197860.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629791473409.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629792339889.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629792857608.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629792857608.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629794527419.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629794928636.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629799214191.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629799873386.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629800324721.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629800748639.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629802656916.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629802697318.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629803111769.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629803529598.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629805387647.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629806856156.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629807579330.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/1629808046783.png">
<meta property="article:published_time" content="2022-12-03T10:42:12.000Z">
<meta property="article:modified_time" content="2022-12-03T10:48:46.922Z">
<meta property="article:author" content="Daorong Xing">
<meta property="article:tag" content="Spring">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://daorongxing.gitee.io/images/image-20210729171139088.png">

<link rel="canonical" href="https://daorongxing.gitee.io/post/3701/">


<script id="page-configurations">
  // https://hexo.io/docs/variables.html
  CONFIG.page = {
    sidebar: "",
    isHome : false,
    isPost : true,
    lang   : 'zh-CN'
  };
</script>

  <title>Spring_1 | 邢道荣的个人博客</title>
  






  <noscript>
  <style>
  .use-motion .brand,
  .use-motion .menu-item,
  .sidebar-inner,
  .use-motion .post-block,
  .use-motion .pagination,
  .use-motion .comments,
  .use-motion .post-header,
  .use-motion .post-body,
  .use-motion .collection-header { opacity: initial; }

  .use-motion .site-title,
  .use-motion .site-subtitle {
    opacity: initial;
    top: initial;
  }

  .use-motion .logo-line-before i { left: initial; }
  .use-motion .logo-line-after i { right: initial; }
  </style>
</noscript>

</head>

<body itemscope itemtype="http://schema.org/WebPage">
  <div class="container use-motion">
    <div class="headband"></div>

    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏">
      <span class="toggle-line toggle-line-first"></span>
      <span class="toggle-line toggle-line-middle"></span>
      <span class="toggle-line toggle-line-last"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <span class="logo-line-before"><i></i></span>
      <h1 class="site-title">邢道荣的个人博客</h1>
      <span class="logo-line-after"><i></i></span>
    </a>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger">
        <i class="fa fa-search fa-fw fa-lg"></i>
    </div>
  </div>
</div>




<nav class="site-nav">
  <ul id="menu" class="main-menu menu">
        <li class="menu-item menu-item-home">

    <a href="/" rel="section"><i class="fa fa-home fa-fw"></i>首页</a>

  </li>
        <li class="menu-item menu-item-about">

    <a href="/about/" rel="section"><i class="fa fa-user fa-fw"></i>关于</a>

  </li>
        <li class="menu-item menu-item-tags">

    <a href="/tags/" rel="section"><i class="fa fa-tags fa-fw"></i>标签</a>

  </li>
        <li class="menu-item menu-item-categories">

    <a href="/categories/" rel="section"><i class="fa fa-th fa-fw"></i>分类</a>

  </li>
        <li class="menu-item menu-item-archives">

    <a href="/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>归档</a>

  </li>
      <li class="menu-item menu-item-search">
        <a role="button" class="popup-trigger"><i class="fa fa-search fa-fw"></i>搜索
        </a>
      </li>
  </ul>
</nav>



  <div class="search-pop-overlay">
    <div class="popup search-popup">
        <div class="search-header">
  <span class="search-icon">
    <i class="fa fa-search"></i>
  </span>
  <div class="search-input-container">
    <input autocomplete="off" autocapitalize="off"
           placeholder="搜索..." spellcheck="false"
           type="search" class="search-input">
  </div>
  <span class="popup-btn-close">
    <i class="fa fa-times-circle"></i>
  </span>
</div>
<div id="search-result">
  <div id="no-result">
    <i class="fa fa-spinner fa-pulse fa-5x fa-fw"></i>
  </div>
</div>

    </div>
  </div>

</div>
    </header>

    
  <div class="reading-progress-bar"></div>


    <main class="main">
      <div class="main-inner">
        <div class="content-wrap">
          

          <div class="content post posts-expand">
            

    
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="https://daorongxing.gitee.io/post/3701/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="Daorong Xing">
      <meta itemprop="description" content="这是我的个人博客，记录计算机学习之路！">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="邢道荣的个人博客">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          Spring_1
        </h1>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>
              

              <time title="创建时间：2022-12-03 18:42:12 / 修改时间：18:48:46" itemprop="dateCreated datePublished" datetime="2022-12-03T18:42:12+08:00">2022-12-03</time>
            </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/Spring/" itemprop="url" rel="index"><span itemprop="name">Spring</span></a>
                </span>
            </span>

          <br>
            <span class="post-meta-item" title="本文字数">
              <span class="post-meta-item-icon">
                <i class="far fa-file-word"></i>
              </span>
                <span class="post-meta-item-text">本文字数：</span>
              <span>50k</span>
            </span>
            <span class="post-meta-item" title="阅读时长">
              <span class="post-meta-item-icon">
                <i class="far fa-clock"></i>
              </span>
                <span class="post-meta-item-text">阅读时长 &asymp;</span>
              <span>46 分钟</span>
            </span>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
        <h2 id="Spring-day01"><a href="#Spring-day01" class="headerlink" title="Spring_day01"></a>Spring_day01</h2><p><strong>今日目标</strong></p>
<blockquote>
<ul>
<li>掌握Spring相关概念</li>
<li>完成IOC&#x2F;DI的入门案例编写</li>
<li>掌握IOC的相关配置与使用</li>
<li>掌握DI的相关配置与使用</li>
</ul>
</blockquote>
<h2 id="1，课程介绍"><a href="#1，课程介绍" class="headerlink" title="1，课程介绍"></a>1，课程介绍</h2><p>对于一门新技术，我们需要从<code>为什么要学</code>、<code>学什么</code>以及<code>怎么学</code>这三个方向入手来学习。那对于Spring来说:</p>
<h3 id="1-1-为什么要学"><a href="#1-1-为什么要学" class="headerlink" title="1.1 为什么要学?"></a>1.1 为什么要学?</h3><ul>
<li><p>从使用和占有率看</p>
<ul>
<li><p>Spring在市场的占有率与使用率高</p>
</li>
<li><p>Spring在企业的技术选型命中率高</p>
</li>
<li><p>所以说,Spring技术是JavaEE开发必备技能，企业开发技术选型命中率&gt;&#x3D;&#x3D;90%&#x3D;&#x3D;</p>
<p><img src="/images/image-20210729171139088.png"></p>
<p><strong>说明</strong>:对于未使用Spring的项目一般都是些比较老的项目，大多都处于维护阶段。</p>
</li>
</ul>
</li>
<li><p>从专业角度看</p>
<ul>
<li>随着时代发展，软件规模与功能都呈几何式增长，开发难度也在不断递增，该如何解决?<ul>
<li>Spring可以&#x3D;&#x3D;简化开发&#x3D;&#x3D;，降低企业级开发的复杂性，使开发变得更简单快捷</li>
</ul>
</li>
<li>随着项目规模与功能的增长,遇到的问题就会增多，为了解决问题会引入更多的框架，这些框架如何协调工作?<ul>
<li>Spring可以&#x3D;&#x3D;框架整合&#x3D;&#x3D;，高效整合其他技术，提高企业级应用开发与运行效率</li>
</ul>
</li>
</ul>
<p>综上所述，&#x3D;&#x3D;Spring是一款非常优秀而且功能强大的框架，不仅要学，而且还要学好。&#x3D;&#x3D;</p>
</li>
</ul>
<h3 id="1-2-学什么"><a href="#1-2-学什么" class="headerlink" title="1.2 学什么?"></a>1.2 学什么?</h3><p>从上面的介绍中，我们可以看到Spring框架主要的优势是在<code>简化开发</code>和<code>框架整合</code>上，至于如何实现就是咱们要学习Spring框架的主要内容:</p>
<ul>
<li><p>简化开发: Spring框架中提供了两个大的核心技术，分别是:</p>
<ul>
<li>&#x3D;&#x3D;IOC&#x3D;&#x3D;</li>
<li>&#x3D;&#x3D;AOP&#x3D;&#x3D;<ul>
<li>&#x3D;&#x3D;事务处理&#x3D;&#x3D;</li>
</ul>
</li>
</ul>
<p> 1.Spring的简化操作都是基于这两块内容,所以这也是Spring学习中最为重要的两个知识点。</p>
<p> 2.事务处理属于Spring中AOP的具体应用，可以简化项目中的事务管理，也是Spring技术中的一大亮点。</p>
</li>
<li><p>框架整合: Spring在框架整合这块已经做到了极致，它可以整合市面上几乎所有主流框架，比如:</p>
<ul>
<li>&#x3D;&#x3D;MyBatis&#x3D;&#x3D;</li>
<li>MyBatis-plus</li>
<li>Struts</li>
<li>Struts2</li>
<li>Hibernate</li>
<li>……</li>
</ul>
<p>这些框架中，我们目前只学习了MyBatis，所以在Spring框架的学习中，主要是学习如何整合MyBatis。</p>
<p>综上所述，对于Spring的学习，主要学习四块内容:</p>
<p>&#x3D;&#x3D;(1)IOC,(2)整合Mybatis(IOC的具体应用)，(3)AOP,(4)声明式事务(AOP的具体应用)&#x3D;&#x3D;</p>
</li>
</ul>
<h3 id="1-3-怎么学"><a href="#1-3-怎么学" class="headerlink" title="1.3 怎么学?"></a>1.3 怎么学?</h3><ul>
<li>学习Spring框架设计思想<ul>
<li>对于Spring来说，它能迅速占领全球市场，不只是说它的某个功能比较强大，更重要是在它的<code>思想</code>上。</li>
</ul>
</li>
<li>学习基础操作，思考操作与思想间的联系<ul>
<li>掌握了Spring的设计思想，然后就需要通过一些基础操作来思考操作与思想之间的关联关系</li>
</ul>
</li>
<li>学习案例，熟练应用操作的同时，体会思想<ul>
<li>会了基础操作后，就需要通过大量案例来熟练掌握框架的具体应用，加深对设计思想的理解。</li>
</ul>
</li>
</ul>
<p>介绍完<code>为什么要学</code>、<code>学什么</code>和<code>怎么学</code>Spring框架后，大家需要重点掌握的是:</p>
<ul>
<li>Spring很优秀，需要认真重点的学习</li>
<li>Spring的学习主线是IOC、AOP、声明式事务和整合MyBais</li>
</ul>
<p>接下来，咱们就开始进入Spring框架的学习。</p>
<h2 id="2，Spring相关概念"><a href="#2，Spring相关概念" class="headerlink" title="2，Spring相关概念"></a>2，Spring相关概念</h2><h3 id="2-1-初识Spring"><a href="#2-1-初识Spring" class="headerlink" title="2.1 初识Spring"></a>2.1 初识Spring</h3><p>在这一节，主要通过以下两个点来了解下Spring:</p>
<h4 id="2-1-1-Spring家族"><a href="#2-1-1-Spring家族" class="headerlink" title="2.1.1 Spring家族"></a>2.1.1 Spring家族</h4><ul>
<li><p>官网：<a href="https://spring.io，从官网我们可以大概了解到：">https://spring.io，从官网我们可以大概了解到：</a></p>
<ul>
<li>Spring能做什么:用以开发web、微服务以及分布式系统等,光这三块就已经占了JavaEE开发的九成多。</li>
<li>Spring并不是单一的一个技术，而是一个大家族，可以从官网的<code>Projects</code>中查看其包含的所有技术。</li>
</ul>
</li>
<li><p>Spring发展到今天已经形成了一种开发的生态圈,Spring提供了若干个项目,每个项目用于完成特定的功能。</p>
<ul>
<li><p>Spring已形成了完整的生态圈，也就是说我们可以完全使用Spring技术完成整个项目的构建、设计与开发。</p>
</li>
<li><p>Spring有若干个项目，可以根据需要自行选择，把这些个项目组合起来，起了一个名称叫&#x3D;&#x3D;全家桶&#x3D;&#x3D;，如下图所示</p>
<p><img src="/images/image-20210729171850181.png"></p>
<p><strong>说明:</strong></p>
<p>图中的图标都代表什么含义，可以进入<code>https://spring.io/projects</code>网站进行对比查看。</p>
<p>这些技术并不是所有的都需要学习，额外需要重点关注<code>Spring Framework</code>、<code>SpringBoot</code>和<code>SpringCloud</code>:</p>
<p><img src="/images/1629714811435.png"></p>
<ul>
<li>Spring Framework:Spring框架，是Spring中最早最核心的技术，也是所有其他技术的基础。</li>
<li>SpringBoot:Spring是来简化开发，而SpringBoot是来帮助Spring在简化的基础上能更快速进行开发。</li>
<li>SpringCloud:这个是用来做分布式之微服务架构的相关开发。</li>
</ul>
<p>除了上面的这三个技术外，还有很多其他的技术，也比较流行，如SpringData,SpringSecurity等，这些都可以被应用在我们的项目中。我们今天所学习的Spring其实指的是&#x3D;&#x3D;Spring Framework&#x3D;&#x3D;。</p>
</li>
</ul>
</li>
</ul>
<h4 id="2-1-2-了解Spring发展史"><a href="#2-1-2-了解Spring发展史" class="headerlink" title="2.1.2 了解Spring发展史"></a>2.1.2 了解Spring发展史</h4><p> 接下来我们介绍下Spring Framework这个技术是如何来的呢?</p>
<p><img src="/images/image-20210729171926576.png"></p>
<p>Spring发展史</p>
<ul>
<li>IBM(IT公司-国际商业机器公司)在1997年提出了EJB思想,早期的JAVAEE开发大都基于该思想。</li>
<li>Rod Johnson(Java和J2EE开发领域的专家)在2002年出版的<code>Expert One-on-One J2EE Design and Development</code>,书中有阐述在开发中使用EJB该如何做。</li>
<li>Rod Johnson在2004年出版的<code>Expert One-on-One J2EE Development without EJB</code>,书中提出了比EJB思想更高效的实现方案，并且在同年将方案进行了具体的落地实现，这个实现就是Spring1.0。</li>
<li>随着时间推移，版本不断更新维护，目前最新的是Spring5<ul>
<li>Spring1.0是纯配置文件开发</li>
<li>Spring2.0为了简化开发引入了注解开发，此时是配置文件加注解的开发方式</li>
<li>Spring3.0已经可以进行纯注解开发，使开发效率大幅提升，我们的课程会以注解开发为主</li>
<li>Spring4.0根据JDK的版本升级对个别API进行了调整</li>
<li>Spring5.0已经全面支持JDK8，现在Spring最新的是5系列所以建议大家把JDK安装成1.8版</li>
</ul>
</li>
</ul>
<p>本节介绍了Spring家族与Spring的发展史，需要大家重点掌握的是:</p>
<ul>
<li>今天所学的Spring其实是Spring家族中的Spring Framework</li>
<li>Spring Framework是Spring家族中其他框架的底层基础，学好Spring可以为其他Spring框架的学习打好基础</li>
</ul>
<h3 id="2-2-Spring系统架构"><a href="#2-2-Spring系统架构" class="headerlink" title="2.2 Spring系统架构"></a>2.2 Spring系统架构</h3><p>前面我们说spring指的是Spring Framework,那么它其中都包含哪些内容以及我们该如何学习这个框架?</p>
<p>针对这些问题，我们将从<code>系统架构图</code>和<code>课程学习路线</code>来进行说明:</p>
<h4 id="2-2-1-系统架构图"><a href="#2-2-1-系统架构图" class="headerlink" title="2.2.1 系统架构图"></a>2.2.1 系统架构图</h4><ul>
<li><p>Spring Framework是Spring生态圈中最基础的项目，是其他项目的根基。</p>
</li>
<li><p>Spring Framework的发展也经历了很多版本的变更，每个版本都有相应的调整</p>
<p><img src="/images/image-20210729172153796.png"></p>
</li>
<li><p>Spring Framework的5版本目前没有最新的架构图，而最新的是4版本，所以接下来主要研究的是4的架构图</p>
<p><img src="/images/1629720945720.png"></p>
<p>(1)核心层</p>
<ul>
<li>Core Container:核心容器，这个模块是Spring最核心的模块，其他的都需要依赖该模块</li>
</ul>
<p>(2)AOP层</p>
<ul>
<li>AOP:面向切面编程，它依赖核心层容器，目的是&#x3D;&#x3D;在不改变原有代码的前提下对其进行功能增强&#x3D;&#x3D;</li>
<li>Aspects:AOP是思想,Aspects是对AOP思想的具体实现</li>
</ul>
<p>(3)数据层</p>
<ul>
<li>Data Access:数据访问，Spring全家桶中有对数据访问的具体实现技术</li>
<li>Data Integration:数据集成，Spring支持整合其他的数据层解决方案，比如Mybatis</li>
<li>Transactions:事务，Spring中事务管理是Spring AOP的一个具体实现，也是后期学习的重点内容</li>
</ul>
<p>(4)Web层</p>
<ul>
<li>这一层的内容将在SpringMVC框架具体学习</li>
</ul>
<p>(5)Test层</p>
<ul>
<li>Spring主要整合了Junit来完成单元测试和集成测试</li>
</ul>
</li>
</ul>
<h4 id="2-2-2-课程学习路线"><a href="#2-2-2-课程学习路线" class="headerlink" title="2.2.2 课程学习路线"></a>2.2.2 课程学习路线</h4><p>介绍完Spring的体系结构后，从中我们可以得出对于Spring的学习主要包含四部分内容，分别是:</p>
<ul>
<li>&#x3D;&#x3D;Spring的IOC&#x2F;DI&#x3D;&#x3D;</li>
<li>&#x3D;&#x3D;Spring的AOP&#x3D;&#x3D;</li>
<li>&#x3D;&#x3D;AOP的具体应用,事务管理&#x3D;&#x3D;</li>
<li>&#x3D;&#x3D;IOC&#x2F;DI的具体应用,整合Mybatis&#x3D;&#x3D;</li>
</ul>
<p><img src="/images/1629722300996.png"></p>
<p>对于这节的内容，大家重点要记住的是Spring需要学习的四部分内容。接下来就从第一部分开始学起。</p>
<h3 id="2-3-Spring核心概念"><a href="#2-3-Spring核心概念" class="headerlink" title="2.3 Spring核心概念"></a>2.3 Spring核心概念</h3><p>在Spring核心概念这部分内容中主要包含<code>IOC/DI</code>、<code>IOC容器</code>和<code>Bean</code>,那么问题就来了，这些都是什么呢?</p>
<h4 id="2-3-1-目前项目中的问题"><a href="#2-3-1-目前项目中的问题" class="headerlink" title="2.3.1 目前项目中的问题"></a>2.3.1 目前项目中的问题</h4><p>一个概念的提出，总是因为有对应的问题需要去解决，那么我们就需要先分析下目前咱们代码在编写过程中遇到的问题:</p>
<p><img src="/images/1629723232339.png"></p>
<p>(1)业务层需要调用数据层的方法，就需要在业务层new数据层的对象</p>
<p>(2)如果数据层的实现类发生变化，那么业务层的代码也需要跟着改变，发生变更后，都需要进行编译打包和重部署</p>
<p>(3)所以，现在代码在编写的过程中存在的问题是：&#x3D;&#x3D; <strong>耦合度偏高</strong> &#x3D;&#x3D;</p>
<p>针对这个问题，该如何解决呢?</p>
<p><img src="/images/1629724206002.png"></p>
<p>我们就想，如果能把框中的内容给去掉，不就可以降低依赖了么，但是又会引入新的问题，去掉以后程序能运行么?</p>
<p>答案肯定是不行，因为bookDao没有赋值为Null，强行运行就会出空指针异常。</p>
<p>所以现在的问题就是，业务层不想new对象，运行的时候又需要这个对象，该咋办呢?</p>
<p>针对这个问题，Spring就提出了一个解决方案:</p>
<ul>
<li>使用对象时，<mark>在程序中不要主动使用new产生对象，转换为由&#x3D;&#x3D;外部&#x3D;&#x3D;提供对象</mark></li>
</ul>
<p>这种实现思就是Spring的一个核心概念</p>
<h4 id="2-3-2-IOC、IOC容器、Bean、DI"><a href="#2-3-2-IOC、IOC容器、Bean、DI" class="headerlink" title="2.3.2 IOC、IOC容器、Bean、DI"></a>2.3.2 IOC、IOC容器、Bean、DI</h4><ol>
<li>&#x3D;&#x3D;IOC（Inversion of Control）控制反转&#x3D;&#x3D;</li>
</ol>
<p>(1)什么是控制反转呢？</p>
<ul>
<li>使用对象时，由主动new产生对象转换为由&#x3D;&#x3D;外部&#x3D;&#x3D;提供对象，此过程中对象创建控制权由程序转移到外部，此思想称为控制反转。<ul>
<li>业务层要用数据层的类对象，以前是自己<code>new</code>的</li>
<li>现在自己不new了，交给<code>别人[外部]</code>来创建对象</li>
<li><code>别人[外部]</code>就反转控制了数据层对象的创建权</li>
<li>这种思想就是控制反转</li>
<li>别人[外部]指定是什么呢?继续往下学</li>
</ul>
</li>
</ul>
<p>(2)Spring和IOC之间的关系是什么呢?</p>
<ul>
<li>Spring技术对IOC思想进行了<strong>实现</strong></li>
<li>Spring提供了一个容器，称为&#x3D;&#x3D;IOC容器&#x3D;&#x3D;，用来充当IOC思想中的”外部”， IOC容器是IOC思想的具体实现</li>
<li>IOC思想中的<code>别人[外部]</code>指的就是Spring的IOC容器</li>
</ul>
<p>(3)IOC容器的作用以及内部存放的是什么?</p>
<ul>
<li>IOC容器<strong>负责对象的创建</strong>、初始化等一系列工作，其中包含了数据层和业务层的类对象</li>
<li>被创建或被管理的<strong>对象</strong>在IOC容器中统称为**&#x3D;&#x3D;Bean&#x3D;&#x3D;**</li>
<li>IOC容器中放的就是一个个的Bean对象</li>
</ul>
<p>(4)当IOC容器中创建好service和dao对象后，程序能正确执行么?</p>
<ul>
<li>不行，因为service运行需要依赖dao对象</li>
<li>IOC容器中虽然有service和dao对象</li>
<li>但是service对象和dao对象没有任何关系</li>
<li>需要把dao对象交给service,也就是说要<strong>绑定service和dao对象之间的关系</strong></li>
</ul>
<p>像这种在容器中建立对象与对象之间的绑定关系就要用到DI:</p>
<ol start="2">
<li>&#x3D;&#x3D;DI（Dependency Injection）依赖注入&#x3D;&#x3D;</li>
</ol>
<p><img src="/images/1629735078619.png"></p>
<p>(1)什么是依赖注入呢?</p>
<ul>
<li>在容器中建立bean与bean之间的依赖关系的整个过程，称为依赖注入<ul>
<li>业务层要用数据层的类对象，以前是自己<code>new</code>的</li>
<li>现在自己不new了，靠<code>别人[外部其实指的就是IOC容器]</code>来给注入进来</li>
<li>这种思想就是依赖注入</li>
</ul>
</li>
</ul>
<p>(2)IOC容器中哪些bean之间要建立依赖关系呢?</p>
<ul>
<li>这个需要程序员根据业务需求提前建立好关系，如业务层需要依赖数据层，service就要和dao建立依赖关系</li>
</ul>
<p>介绍完Spring的IOC和DI的概念后，我们会发现这两个概念的最终目标就是:&#x3D;&#x3D;充分解耦&#x3D;&#x3D;，具体实现靠:</p>
<ul>
<li>使用IOC容器管理bean（IOC)</li>
<li>在IOC容器内将有依赖关系的bean进行关系绑定（DI）</li>
<li>最终结果为:使用对象时不仅可以直接从IOC容器中获取，并且获取到的bean已经绑定了所有的依赖关系.</li>
</ul>
<h4 id="2-3-3-核心概念小结"><a href="#2-3-3-核心概念小结" class="headerlink" title="2.3.3 核心概念小结"></a>2.3.3 核心概念小结</h4><p>这节比较重要，重点要理解<code>什么是IOC/DI思想</code>、<code>什么是IOC容器</code>和<code>什么是Bean</code>：</p>
<p>(1)什么IOC&#x2F;DI思想?</p>
<ul>
<li>IOC:控制反转，控制反转的是对象的创建权</li>
<li>DI:依赖注入，绑定对象与对象之间的依赖关系</li>
</ul>
<p>(2)什么是IOC容器?</p>
<p>Spring创建了一个容器用来存放所创建的对象，这个容器就叫IOC容器</p>
<p>(3)什么是Bean?</p>
<p>容器中所存放的一个个对象就叫Bean或Bean对象</p>
<h2 id="3，入门案例"><a href="#3，入门案例" class="headerlink" title="3，入门案例"></a>3，入门案例</h2><p>介绍完Spring的核心概念后，接下来我们得思考一个问题就是，Spring到底是如何来实现IOC和DI的，那接下来就通过一些简单的入门案例，来演示下具体实现过程:</p>
<h3 id="3-1-IOC入门案例"><a href="#3-1-IOC入门案例" class="headerlink" title="3.1 IOC入门案例"></a>3.1 IOC入门案例</h3><p>对于入门案例，我们得先<code>分析思路</code>然后再<code>代码实现</code>，</p>
<h4 id="3-1-1-入门案例思路分析"><a href="#3-1-1-入门案例思路分析" class="headerlink" title="3.1.1 入门案例思路分析"></a>3.1.1 入门案例思路分析</h4><p>(1)Spring是使用容器来管理bean对象的，那么管什么? </p>
<ul>
<li>主要管理项目中所使用到的类对象，比如(Service和Dao)</li>
</ul>
<p>(2)如何将被管理的对象告知IOC容器?</p>
<ul>
<li>使用配置文件</li>
</ul>
<p>(3)被管理的对象交给IOC容器，要想从容器中获取对象，就先得思考如何获取到IOC容器?</p>
<ul>
<li>Spring框架提供相应的接口</li>
</ul>
<p>(4)IOC容器得到后，如何从容器中获取bean?</p>
<ul>
<li>调用Spring框架提供对应接口中的方法</li>
</ul>
<p>(5)使用Spring导入哪些坐标?</p>
<ul>
<li>用别人的东西，就需要在pom.xml添加对应的依赖</li>
</ul>
<h4 id="3-1-2-入门案例代码实现"><a href="#3-1-2-入门案例代码实现" class="headerlink" title="3.1.2 入门案例代码实现"></a>3.1.2 入门案例代码实现</h4><blockquote>
<p>需求分析:将BookServiceImpl和BookDaoImpl交给Spring管理，并从容器中获取对应的bean对象进行方法调用。</p>
<p>1.创建Maven的java项目</p>
<p>2.pom.xml添加Spring的依赖jar包</p>
<p>3.创建BookService,BookServiceImpl，BookDao和BookDaoImpl四个类</p>
<p>4.resources下添加spring配置文件，并完成bean的配置</p>
<p>5.使用Spring提供的接口完成IOC容器的创建</p>
<p>6.从容器中获取对象进行方法调用</p>
</blockquote>
<h5 id="步骤1-创建Maven项目"><a href="#步骤1-创建Maven项目" class="headerlink" title="步骤1:创建Maven项目"></a>步骤1:创建Maven项目</h5><p><img src="/images/1629734010072.png"></p>
<h5 id="步骤2-添加Spring的依赖jar包"><a href="#步骤2-添加Spring的依赖jar包" class="headerlink" title="步骤2:添加Spring的依赖jar包"></a>步骤2:添加Spring的依赖jar包</h5><p>pom.xml</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dependencies</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-context<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">version</span>&gt;</span>5.2.10.RELEASE<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>junit<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>junit<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">version</span>&gt;</span>4.12<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">scope</span>&gt;</span>test<span class="tag">&lt;/<span class="name">scope</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependencies</span>&gt;</span></span><br></pre></td></tr></table></figure>

<h5 id="步骤3-添加案例中需要的类"><a href="#步骤3-添加案例中需要的类" class="headerlink" title="步骤3:添加案例中需要的类"></a>步骤3:添加案例中需要的类</h5><p>创建BookService,BookServiceImpl，BookDao和BookDaoImpl四个类</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">BookDao</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">BookDaoImpl</span> <span class="keyword">implements</span> <span class="title class_">BookDao</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;book dao save ...&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">BookService</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">BookServiceImpl</span> <span class="keyword">implements</span> <span class="title class_">BookService</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> <span class="type">BookDao</span> <span class="variable">bookDao</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">BookDaoImpl</span>();</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;book service save ...&quot;</span>);</span><br><span class="line">        bookDao.save();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h5 id="步骤4-添加spring配置文件"><a href="#步骤4-添加spring配置文件" class="headerlink" title="步骤4:添加spring配置文件"></a>步骤4:添加spring配置文件</h5><p>resources下添加spring配置文件applicationContext.xml，并完成bean的配置</p>
<p><img src="/images/1629734336440.png"></p>
<h5 id="步骤5-在配置文件中完成bean的配置"><a href="#步骤5-在配置文件中完成bean的配置" class="headerlink" title="步骤5:在配置文件中完成bean的配置"></a>步骤5:在配置文件中完成bean的配置</h5><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version=<span class="string">&quot;1.0&quot;</span> encoding=<span class="string">&quot;UTF-8&quot;</span>?&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">beans</span> <span class="attr">xmlns</span>=<span class="string">&quot;http://www.springframework.org/schema/beans&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:xsi</span>=<span class="string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xsi:schemaLocation</span>=<span class="string">&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd&quot;</span>&gt;</span></span><br><span class="line"> </span><br><span class="line">    <span class="comment">&lt;!--bean标签标示配置bean</span></span><br><span class="line"><span class="comment">    	id属性标示给bean起名字</span></span><br><span class="line"><span class="comment">    	class属性表示给bean定义类型</span></span><br><span class="line"><span class="comment">	--&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;bookDao&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.dao.impl.BookDaoImpl&quot;</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;bookService&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.service.impl.BookServiceImpl&quot;</span>/&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;/<span class="name">beans</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p><strong>&#x3D;&#x3D;注意事项：bean定义时id属性在同一个上下文中(配置文件)不能重复&#x3D;&#x3D;</strong></p>
<h5 id="步骤6-获取IOC容器"><a href="#步骤6-获取IOC容器" class="headerlink" title="步骤6:获取IOC容器"></a>步骤6:获取IOC容器</h5><p>使用Spring提供的接口完成IOC容器的创建，创建App类，编写main方法</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">App</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="comment">//获取IOC容器</span></span><br><span class="line">		<span class="type">ApplicationContext</span> <span class="variable">ctx</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ClassPathXmlApplicationContext</span>(<span class="string">&quot;applicationContext.xml&quot;</span>); </span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h5 id="步骤7-从容器中获取对象进行方法调用"><a href="#步骤7-从容器中获取对象进行方法调用" class="headerlink" title="步骤7:从容器中获取对象进行方法调用"></a>步骤7:从容器中获取对象进行方法调用</h5><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">App</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="comment">//获取IOC容器</span></span><br><span class="line">		<span class="type">ApplicationContext</span> <span class="variable">ctx</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ClassPathXmlApplicationContext</span>(<span class="string">&quot;applicationContext.xml&quot;</span>); </span><br><span class="line"><span class="comment">//        BookDao bookDao = (BookDao) ctx.getBean(&quot;bookDao&quot;);</span></span><br><span class="line"><span class="comment">//        bookDao.save();</span></span><br><span class="line">        <span class="type">BookService</span> <span class="variable">bookService</span> <span class="operator">=</span> (BookService) ctx.getBean(<span class="string">&quot;bookService&quot;</span>);</span><br><span class="line">        bookService.save();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h5 id="步骤8-运行程序"><a href="#步骤8-运行程序" class="headerlink" title="步骤8:运行程序"></a>步骤8:运行程序</h5><p>测试结果为：</p>
<p><img src="/images/image-20210729184337603.png"></p>
<p>Spring的IOC入门案例已经完成，但是在<code>BookServiceImpl</code>的类中依然存在<code>BookDaoImpl</code>对象的new操作，它们之间的耦合度还是比较高，这块该如何解决，就需要用到下面的<code>DI:依赖注入</code>。</p>
<h3 id="3-2-DI入门案例"><a href="#3-2-DI入门案例" class="headerlink" title="3.2 DI入门案例"></a>3.2 DI入门案例</h3><p>对于DI的入门案例，我们依然先<code>分析思路</code>然后再<code>代码实现</code>，</p>
<h4 id="3-2-1-入门案例思路分析"><a href="#3-2-1-入门案例思路分析" class="headerlink" title="3.2.1 入门案例思路分析"></a>3.2.1 入门案例思路分析</h4><p>(1)要想实现依赖注入，必须要基于IOC管理Bean</p>
<ul>
<li>DI的入门案例要依赖于前面IOC的入门案例</li>
</ul>
<p>(2)Service中使用new形式创建的Dao对象是否保留?</p>
<ul>
<li>需要删除掉，最终要使用IOC容器中的bean对象</li>
</ul>
<p>(3)Service中需要的Dao对象如何进入到Service中?</p>
<ul>
<li>在Service中提供方法，让Spring的IOC容器可以通过该方法传入bean对象</li>
</ul>
<p>(4)Service与Dao间的关系如何描述?</p>
<ul>
<li>使用配置文件</li>
</ul>
<h4 id="3-2-2-入门案例代码实现"><a href="#3-2-2-入门案例代码实现" class="headerlink" title="3.2.2 入门案例代码实现"></a>3.2.2 入门案例代码实现</h4><blockquote>
<p>需求:基于IOC入门案例，在BookServiceImpl类中删除new对象的方式，使用Spring的DI完成Dao层的注入</p>
<p>1.删除业务层中使用new的方式创建的dao对象</p>
<p>2.在业务层提供BookDao的setter方法</p>
<p>3.在配置文件中添加依赖注入的配置</p>
<p>4.运行程序调用方法</p>
</blockquote>
<h5 id="步骤1-去除代码中的new"><a href="#步骤1-去除代码中的new" class="headerlink" title="步骤1: 去除代码中的new"></a>步骤1: 去除代码中的new</h5><p>在BookServiceImpl类中，删除业务层中使用new的方式创建的dao对象</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">BookServiceImpl</span> <span class="keyword">implements</span> <span class="title class_">BookService</span> &#123;</span><br><span class="line">    <span class="comment">//删除业务层中使用new的方式创建的dao对象</span></span><br><span class="line">    <span class="keyword">private</span> BookDao bookDao;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;book service save ...&quot;</span>);</span><br><span class="line">        bookDao.save();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h5 id="步骤2-为属性提供setter方法"><a href="#步骤2-为属性提供setter方法" class="headerlink" title="步骤2:为属性提供setter方法"></a>步骤2:为属性提供setter方法</h5><p>在BookServiceImpl类中,为BookDao提供setter方法</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">BookServiceImpl</span> <span class="keyword">implements</span> <span class="title class_">BookService</span> &#123;</span><br><span class="line">    <span class="comment">//删除业务层中使用new的方式创建的dao对象</span></span><br><span class="line">    <span class="keyword">private</span> BookDao bookDao;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;book service save ...&quot;</span>);</span><br><span class="line">        bookDao.save();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//提供对应的set方法</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setBookDao</span><span class="params">(BookDao bookDao)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.bookDao = bookDao;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h5 id="步骤3-修改配置完成注入"><a href="#步骤3-修改配置完成注入" class="headerlink" title="步骤3:修改配置完成注入"></a>步骤3:修改配置完成注入</h5><p>在配置文件中添加依赖注入的配置</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version=<span class="string">&quot;1.0&quot;</span> encoding=<span class="string">&quot;UTF-8&quot;</span>?&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">beans</span> <span class="attr">xmlns</span>=<span class="string">&quot;http://www.springframework.org/schema/beans&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:xsi</span>=<span class="string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xsi:schemaLocation</span>=<span class="string">&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd&quot;</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--bean标签标示配置bean</span></span><br><span class="line"><span class="comment">    	id属性标示给bean起名字</span></span><br><span class="line"><span class="comment">    	class属性表示给bean定义类型</span></span><br><span class="line"><span class="comment">	--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;bookDao&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.dao.impl.BookDaoImpl&quot;</span>/&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;bookService&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.service.impl.BookServiceImpl&quot;</span>&gt;</span></span><br><span class="line">        <span class="comment">&lt;!--配置server与dao的关系--&gt;</span></span><br><span class="line">        <span class="comment">&lt;!--property标签表示配置当前bean的属性</span></span><br><span class="line"><span class="comment">        		name属性表示配置哪一个具体的属性</span></span><br><span class="line"><span class="comment">        		ref属性表示参照哪一个bean</span></span><br><span class="line"><span class="comment">		--&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;bookDao&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;bookDao&quot;</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;/<span class="name">beans</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p>&#x3D;&#x3D;注意:配置中的两个bookDao的含义是不一样的&#x3D;&#x3D;</p>
<ul>
<li>name&#x3D;”bookDao”中<code>bookDao</code>的作用是让Spring的IOC容器在获取到名称后，将首字母大写，前面加set找对应的<code>setBookDao()</code>方法进行对象注入</li>
<li>ref&#x3D;”bookDao”中<code>bookDao</code>的作用是让Spring能在IOC容器中找到id为<code>bookDao</code>的Bean对象给<code>bookService</code>进行注入</li>
<li>综上所述，对应关系如下:</li>
</ul>
<p><img src="/images/1629736314989.png"></p>
<h5 id="步骤4-运行程序"><a href="#步骤4-运行程序" class="headerlink" title="步骤4:运行程序"></a>步骤4:运行程序</h5><p>运行，测试结果为：</p>
<p><img src="/images/image-20210729184337603.png"></p>
<h2 id="4，IOC相关内容"><a href="#4，IOC相关内容" class="headerlink" title="4，IOC相关内容"></a>4，IOC相关内容</h2><p>通过前面两个案例，我们已经学习了<code>bean如何定义配置</code>，<code>DI如何定义配置</code>以及<code>容器对象如何获取</code>的内容，接下来主要是把这三块内容展开进行详细的讲解，深入的学习下这三部分的内容，首先是bean基础配置。</p>
<h3 id="4-1-bean基础配置"><a href="#4-1-bean基础配置" class="headerlink" title="4.1 bean基础配置"></a>4.1 bean基础配置</h3><p>对于bean的配置中，主要会讲解<code>bean基础配置</code>,<code>bean的别名配置</code>,<code>bean的作用范围配置</code>&#x3D;&#x3D;(重点)&#x3D;&#x3D;,这三部分内容：</p>
<h4 id="4-1-1-bean基础配置-id与class"><a href="#4-1-1-bean基础配置-id与class" class="headerlink" title="4.1.1 bean基础配置(id与class)"></a>4.1.1 bean基础配置(id与class)</h4><p>对于bean的基础配置，在前面的案例中已经使用过:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;bean id=&quot;&quot; class=&quot;&quot;/&gt;</span><br></pre></td></tr></table></figure>

<p>其中，bean标签的功能、使用方式以及id和class属性的作用，我们通过一张图来描述下</p>
<p><img src="/images/image-20210729183500978.png"></p>
<p>这其中需要大家重点掌握的是:&#x3D;&#x3D;bean标签的id和class属性的使用&#x3D;&#x3D;。</p>
<p><strong>思考：</strong></p>
<ul>
<li>class属性能不能写接口如<code>BookDao</code>的类全名呢?</li>
</ul>
<p>答案肯定是不行，因为接口是没办法创建对象的。</p>
<ul>
<li>前面提过为bean设置id时，id必须唯一，但是如果由于命名习惯而产生了分歧后，该如何解决?</li>
</ul>
<p>在解决这个问题之前，我们需要准备下开发环境，对于开发环境我们可以有两种解决方案:</p>
<ul>
<li><p>使用前面IOC和DI的案例</p>
</li>
<li><p>重新搭建一个新的案例环境,目的是方便大家查阅代码</p>
<ul>
<li><p>搭建的内容和前面的案例是一样的，内容如下：</p>
<p><img src="/images/1629769227068.png"></p>
</li>
</ul>
</li>
</ul>
<h4 id="4-1-2-bean的name属性"><a href="#4-1-2-bean的name属性" class="headerlink" title="4.1.2 bean的name属性"></a>4.1.2 bean的name属性</h4><p>环境准备好后，接下来就可以在这个环境的基础上来学习下bean的别名配置，</p>
<p>首先来看下别名的配置说明:</p>
<p><img src="/images/image-20210729183558051.png"></p>
<h5 id="步骤1：配置别名"><a href="#步骤1：配置别名" class="headerlink" title="步骤1：配置别名"></a>步骤1：配置别名</h5><p>打开spring的配置文件applicationContext.xml</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version=<span class="string">&quot;1.0&quot;</span> encoding=<span class="string">&quot;UTF-8&quot;</span>?&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">beans</span> <span class="attr">xmlns</span>=<span class="string">&quot;http://www.springframework.org/schema/beans&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:xsi</span>=<span class="string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xsi:schemaLocation</span>=<span class="string">&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd&quot;</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">&lt;!--name:为bean指定别名，别名可以有多个，使用逗号，分号，空格进行分隔--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;bookService&quot;</span> <span class="attr">name</span>=<span class="string">&quot;service service4 bookEbi&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.service.impl.BookServiceImpl&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;bookDao&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;bookDao&quot;</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">&lt;!--scope：为bean设置作用范围，可选值为单例singloton，非单例prototype--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;bookDao&quot;</span> <span class="attr">name</span>=<span class="string">&quot;dao&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.dao.impl.BookDaoImpl&quot;</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">beans</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p><strong>说明:Ebi全称Enterprise Business Interface，翻译为企业业务接口</strong></p>
<h5 id="步骤2-根据名称容器中获取bean对象"><a href="#步骤2-根据名称容器中获取bean对象" class="headerlink" title="步骤2:根据名称容器中获取bean对象"></a>步骤2:根据名称容器中获取bean对象</h5><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">AppForName</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">ApplicationContext</span> <span class="variable">ctx</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ClassPathXmlApplicationContext</span>(<span class="string">&quot;applicationContext.xml&quot;</span>);</span><br><span class="line">        <span class="comment">//此处根据bean标签的id属性和name属性的任意一个值来获取bean对象</span></span><br><span class="line">        <span class="type">BookService</span> <span class="variable">bookService</span> <span class="operator">=</span> (BookService) ctx.getBean(<span class="string">&quot;service4&quot;</span>);</span><br><span class="line">        bookService.save();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h5 id="步骤3-运行程序"><a href="#步骤3-运行程序" class="headerlink" title="步骤3:运行程序"></a>步骤3:运行程序</h5><p>测试结果为：</p>
<p><img src="/images/image-20210729184337603.png"></p>
<p>&#x3D;&#x3D;注意事项:&#x3D;&#x3D;</p>
<ul>
<li><p>bean依赖注入的ref属性指定bean，必须在容器中存在</p>
<p><img src="/images/1629771744003.png"></p>
</li>
<li><p>如果不存在,则会报错，如下:</p>
<p><img src="/images/1629771880920.png"></p>
<p>这个错误大家需要特别关注下:</p>
<p><img src="/images/1629771972886.png"></p>
<p>获取bean无论是通过id还是name获取，如果无法获取到，将抛出异常&#x3D;&#x3D;NoSuchBeanDefinitionException&#x3D;&#x3D;</p>
</li>
</ul>
<h4 id="4-1-3-bean作用范围scope配置"><a href="#4-1-3-bean作用范围scope配置" class="headerlink" title="4.1.3 bean作用范围scope配置"></a>4.1.3 bean作用范围scope配置</h4><p>关于bean的作用范围是bean属性配置的一个&#x3D;&#x3D;重点&#x3D;&#x3D;内容。</p>
<p>看到这个作用范围，我们就得思考bean的作用范围是来控制bean哪块内容的?</p>
<p>我们先来看下<code>bean作用范围的配置属性</code>:</p>
<p><img src="/images/image-20210729183628138.png"></p>
<h5 id="4-1-3-1-验证IOC容器中对象是否为单例"><a href="#4-1-3-1-验证IOC容器中对象是否为单例" class="headerlink" title="4.1.3.1 验证IOC容器中对象是否为单例"></a>4.1.3.1 验证IOC容器中对象是否为单例</h5><h6 id="验证思路"><a href="#验证思路" class="headerlink" title="验证思路"></a>验证思路</h6><p>​	同一个bean获取两次，将对象打印到控制台，看打印出的地址值是否一致。</p>
<h6 id="具体实现"><a href="#具体实现" class="headerlink" title="具体实现"></a>具体实现</h6><ul>
<li><p>创建一个AppForScope的类，在其main方法中来验证</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">AppForScope</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">ApplicationContext</span> <span class="variable">ctx</span> <span class="operator">=</span> <span class="keyword">new</span> </span><br><span class="line">            <span class="title class_">ClassPathXmlApplicationContext</span>(<span class="string">&quot;applicationContext.xml&quot;</span>);</span><br><span class="line"></span><br><span class="line">        <span class="type">BookDao</span> <span class="variable">bookDao1</span> <span class="operator">=</span> (BookDao) ctx.getBean(<span class="string">&quot;bookDao&quot;</span>);</span><br><span class="line">        <span class="type">BookDao</span> <span class="variable">bookDao2</span> <span class="operator">=</span> (BookDao) ctx.getBean(<span class="string">&quot;bookDao&quot;</span>);</span><br><span class="line">        System.out.println(bookDao1);</span><br><span class="line">        System.out.println(bookDao2);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>打印，观察控制台的打印结果</p>
<p><img src="/images/1629772538893.png"></p>
</li>
<li><p>结论:默认情况下，Spring创建的bean对象都是单例的</p>
</li>
</ul>
<p>获取到结论后，问题就来了，那如果我想创建出来非单例的bean对象，该如何实现呢?</p>
<h5 id="4-1-3-2-配置bean为非单例"><a href="#4-1-3-2-配置bean为非单例" class="headerlink" title="4.1.3.2 配置bean为非单例"></a>4.1.3.2 配置bean为非单例</h5><p>在Spring配置文件中，配置scope属性来实现bean的非单例创建</p>
<ul>
<li><p>在Spring的配置文件中，修改<code>&lt;bean&gt;</code>的scope属性</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;bookDao&quot;</span> <span class="attr">name</span>=<span class="string">&quot;dao&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.dao.impl.BookDaoImpl&quot;</span> <span class="attr">scope</span>=<span class="string">&quot;&quot;</span>/&gt;</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>将scope设置为<code>singleton</code></p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;bookDao&quot;</span> <span class="attr">name</span>=<span class="string">&quot;dao&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.dao.impl.BookDaoImpl&quot;</span> <span class="attr">scope</span>=<span class="string">&quot;singleton&quot;</span>/&gt;</span></span><br></pre></td></tr></table></figure>

<p>运行AppForScope，打印看结果</p>
<p><img src="/images/1629772538893.png"></p>
</li>
<li><p>将scope设置为<code>prototype</code></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;bean id=&quot;bookDao&quot; name=&quot;dao&quot; class=&quot;com.itheima.dao.impl.BookDaoImpl&quot; scope=&quot;prototype&quot;/&gt;</span><br></pre></td></tr></table></figure>

<p>运行AppForScope，打印看结果</p>
<p><img src="/images/1629772928714.png"></p>
</li>
<li><p>结论，使用bean的<code>scope</code>属性可以控制bean的创建是否为单例：</p>
<ul>
<li><code>singleton</code>默认为单例</li>
<li><code>prototype</code>为非单例</li>
</ul>
</li>
</ul>
<h5 id="4-1-3-3-scope使用后续思考"><a href="#4-1-3-3-scope使用后续思考" class="headerlink" title="4.1.3.3 scope使用后续思考"></a>4.1.3.3 scope使用后续思考</h5><p>介绍完<code>scope</code>属性以后，我们来思考几个问题:</p>
<ul>
<li><p>为什么bean默认为单例?</p>
<ul>
<li>bean为单例的意思是在Spring的IOC容器中<strong>只会有该类的一个对象</strong></li>
<li>bean对象只有一个就<strong>避免了对象的频繁创建与销毁</strong>，达到了bean对象的<strong>复用，性能高</strong></li>
</ul>
</li>
<li><p>bean在容器中是单例的，会不会产生<strong>线程安全</strong>问题?</p>
<ul>
<li><p>如果对象是<mark>有状态</mark>对象，即该对象有成员变量可以用来存储数据的，</p>
<p>因为所有请求线程共用一个bean对象，所以会存在线程安全问题。</p>
</li>
<li><p>如果对象是<mark>无状态</mark>对象，即该对象没有成员变量没有进行数据存储的，</p>
<p>因方法中的<strong>局部变量在方法调用完成后会被销毁</strong>，所以不会存在线程安全问题。</p>
</li>
</ul>
</li>
<li><p>哪些bean对象适合交给容器进行管理?</p>
<ul>
<li>表现层对象</li>
<li>业务层对象</li>
<li>数据层对象</li>
<li>工具对象</li>
</ul>
</li>
<li><p>哪些bean对象不适合交给容器进行管理?</p>
<ul>
<li>封装<strong>实例</strong>的域对象，因为会引发线程安全问题，所以不适合。</li>
</ul>
</li>
</ul>
<h4 id="4-14-bean基础配置小结"><a href="#4-14-bean基础配置小结" class="headerlink" title="4.14 bean基础配置小结"></a>4.14 bean基础配置小结</h4><p>关于bean的基础配置中，需要大家掌握以下属性:</p>
<p><img src="/images/1631529887695.png"></p>
<h3 id="4-2-bean实例化"><a href="#4-2-bean实例化" class="headerlink" title="4.2 bean实例化"></a>4.2 bean实例化</h3><p>对象已经能交给Spring的IOC容器来创建了，但是容器是如何来创建对象的呢?</p>
<p>就需要研究下<code>bean的实例化过程</code>，在这块内容中主要解决两部分内容，分别是</p>
<ul>
<li>bean是如何创建的</li>
<li>实例化bean的三种方式，<code>构造方法(重点)</code>,<code>静态工厂</code>，<code>实例工厂()</code>，<code>FactoryBean()(重点)</code></li>
</ul>
<p>在讲解这三种创建方式之前，我们需要先确认一件事:</p>
<p>bean本质上就是对象，对象在new的时候会使用构造方法完成，那创建bean也是使用构造方法完成的。</p>
<p>基于这个知识点出发，我们来验证spring中bean的三种创建方式，</p>
<h4 id="4-2-1-环境准备"><a href="#4-2-1-环境准备" class="headerlink" title="4.2.1 环境准备"></a>4.2.1 环境准备</h4><p>为了方便大家阅读代码，重新准备个开发环境，</p>
<ul>
<li>创建一个Maven项目</li>
<li>pom.xml添加依赖</li>
<li>resources下添加spring的配置文件applicationContext.xml</li>
</ul>
<p>这些步骤和前面的都一致，大家可以快速的拷贝即可，最终项目的结构如下:</p>
<p><img src="/images/1629775585694.png"></p>
<h4 id="4-2-2-构造方法实例化"><a href="#4-2-2-构造方法实例化" class="headerlink" title="4.2.2 构造方法实例化"></a>4.2.2 构造方法实例化</h4><p>在上述的环境下，我们来研究下Spring中的第一种bean的创建方式<code>构造方法实例化</code>:</p>
<h5 id="步骤1-准备需要被创建的类"><a href="#步骤1-准备需要被创建的类" class="headerlink" title="步骤1:准备需要被创建的类"></a>步骤1:准备需要被创建的类</h5><p>准备一个BookDao和BookDaoImpl类</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">BookDao</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">BookDaoImpl</span> <span class="keyword">implements</span> <span class="title class_">BookDao</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;book dao save ...&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h5 id="步骤2-将类配置到Spring容器"><a href="#步骤2-将类配置到Spring容器" class="headerlink" title="步骤2:将类配置到Spring容器"></a>步骤2:将类配置到Spring容器</h5><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version=<span class="string">&quot;1.0&quot;</span> encoding=<span class="string">&quot;UTF-8&quot;</span>?&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">beans</span> <span class="attr">xmlns</span>=<span class="string">&quot;http://www.springframework.org/schema/beans&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:xsi</span>=<span class="string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xsi:schemaLocation</span>=<span class="string">&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd&quot;</span>&gt;</span></span><br><span class="line"></span><br><span class="line">	<span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;bookDao&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.dao.impl.BookDaoImpl&quot;</span>/&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;/<span class="name">beans</span>&gt;</span></span><br></pre></td></tr></table></figure>

<h5 id="步骤3-编写运行程序"><a href="#步骤3-编写运行程序" class="headerlink" title="步骤3:编写运行程序"></a>步骤3:编写运行程序</h5><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">AppForInstanceBook</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">ApplicationContext</span> <span class="variable">ctx</span> <span class="operator">=</span> <span class="keyword">new</span> </span><br><span class="line">            <span class="title class_">ClassPathXmlApplicationContext</span>(<span class="string">&quot;applicationContext.xml&quot;</span>);</span><br><span class="line">        <span class="type">BookDao</span> <span class="variable">bookDao</span> <span class="operator">=</span> (BookDao) ctx.getBean(<span class="string">&quot;bookDao&quot;</span>);</span><br><span class="line">        bookDao.save();</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h5 id="步骤4-类中提供构造函数测试"><a href="#步骤4-类中提供构造函数测试" class="headerlink" title="步骤4:类中提供构造函数测试"></a>步骤4:类中提供构造函数测试</h5><p>在BookDaoImpl类中添加一个无参构造函数，并打印一句话，方便观察结果。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">BookDaoImpl</span> <span class="keyword">implements</span> <span class="title class_">BookDao</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">BookDaoImpl</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;book dao constructor is running ....&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;book dao save ...&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>运行程序，如果控制台有打印构造函数中的输出，说明Spring容器在创建对象的时候也走的是构造函数</p>
<p><img src="/images/1629775972507.png"></p>
<h5 id="步骤5-将构造函数改成private测试"><a href="#步骤5-将构造函数改成private测试" class="headerlink" title="步骤5:将构造函数改成private测试"></a>步骤5:将构造函数改成private测试</h5><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">BookDaoImpl</span> <span class="keyword">implements</span> <span class="title class_">BookDao</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> <span class="title function_">BookDaoImpl</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;book dao constructor is running ....&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;book dao save ...&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>运行程序，能执行成功,说明内部走的依然是构造函数,能访问到类中的私有构造方法,因为无论私有公有都能够被访问，所以我们可以说，<strong>Spring底层用的是反射</strong></p>
<p><img src="/images/1629775972507.png"></p>
<h5 id="步骤6-构造函数中添加一个参数测试"><a href="#步骤6-构造函数中添加一个参数测试" class="headerlink" title="步骤6:构造函数中添加一个参数测试"></a>步骤6:构造函数中添加一个参数测试</h5><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">BookDaoImpl</span> <span class="keyword">implements</span> <span class="title class_">BookDao</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> <span class="title function_">BookDaoImpl</span><span class="params">(<span class="type">int</span> i)</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;book dao constructor is running ....&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;book dao save ...&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>运行程序，</p>
<p>程序会报错，说明Spring底层使用的是<strong>类的无参构造方法</strong>。</p>
<p>（原因：有参构造器通常意味着类要进行实例化，而实例化的类在IOC的单例模式下很容易造成线程安全问题，所以IOC拒绝访问有参构造器生成的对象）</p>
<p><img src="/images/1629776331499.png"></p>
<p><mark>底层是运用反射获取类的无参构造器来构造类的单例对象。</mark></p>
<h4 id="4-2-3-分析Spring的错误信息-简单看看就好了"><a href="#4-2-3-分析Spring的错误信息-简单看看就好了" class="headerlink" title="4.2.3 分析Spring的错误信息(简单看看就好了)"></a>4.2.3 分析Spring的错误信息(简单看看就好了)</h4><p>接下来，我们主要研究下Spring的报错信息来学一学如阅读。</p>
<ul>
<li><p>错误信息从下往上依次查看，因为上面的错误大都是对下面错误的一个包装，最核心错误是在最下面</p>
<blockquote>
<p>Caused by: java.lang.NoSuchMethodException: com.itheima.dao.impl.BookDaoImpl.<code>&lt;init&gt;</code>()</p>
</blockquote>
<ul>
<li>Caused by 翻译为<code>引起</code>，即出现错误的原因</li>
<li>java.lang.NoSuchMethodException:抛出的异常为<code>没有这样的方法异常</code></li>
<li>com.itheima.dao.impl.BookDaoImpl.<code>&lt;init&gt;</code>():哪个类的哪个方法没有被找到导致的异常，<code>&lt;init&gt;</code>()指定是类的构造方法，即该类的无参构造方法</li>
</ul>
</li>
</ul>
<p>如果最后一行错误获取不到错误信息，接下来查看第二层:</p>
<blockquote>
<p> Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.itheima.dao.impl.BookDaoImpl]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.itheima.dao.impl.BookDaoImpl.<code>&lt;init&gt;</code>()</p>
</blockquote>
<ul>
<li>nested:嵌套的意思，后面的异常内容和最底层的异常是一致的<ul>
<li>Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.itheima.dao.impl.BookDaoImpl]: No default constructor found; <ul>
<li>Caused by: <code>引发</code></li>
<li>BeanInstantiationException:翻译为<code>bean实例化异常</code></li>
<li>No default constructor found:没有一个默认的构造函数被发现</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>看到这其实错误已经比较明显，给大家个练习，把倒数第三层的错误分析下吧:</p>
<blockquote>
<p> Exception in thread “main” org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘bookDao’ defined in class path resource [applicationContext.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.itheima.dao.impl.BookDaoImpl]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.itheima.dao.impl.BookDaoImpl.<code>&lt;init&gt;</code>()。</p>
</blockquote>
<p>至此，关于Spring的构造方法实例化就已经学习完了，因为每一个类默认都会提供一个无参构造函数，所以其实真正在使用这种方式的时候，我们什么也不需要做。这也是我们以后比较常用的一种方式。</p>
<h4 id="4-2-4-静态工厂实例化"><a href="#4-2-4-静态工厂实例化" class="headerlink" title="4.2.4 静态工厂实例化"></a>4.2.4 静态工厂实例化</h4><p>接下来研究Spring中的第二种bean的创建方式<code>静态工厂实例化</code>:</p>
<h5 id="4-2-4-1-工厂方式创建bean"><a href="#4-2-4-1-工厂方式创建bean" class="headerlink" title="4.2.4.1 工厂方式创建bean"></a>4.2.4.1 工厂方式创建bean</h5><p>在讲这种方式之前，我们需要先回顾一个知识点是使用工厂来创建对象的方式:</p>
<p>(1)准备一个OrderDao和OrderDaoImpl类</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">OrderDao</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">OrderDaoImpl</span> <span class="keyword">implements</span> <span class="title class_">OrderDao</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;order dao save ...&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>(2)创建一个工厂类OrderDaoFactory并提供一个&#x3D;&#x3D;静态方法&#x3D;&#x3D;</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//静态工厂创建对象</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">OrderDaoFactory</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> OrderDao <span class="title function_">getOrderDao</span><span class="params">()</span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">OrderDaoImpl</span>();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>(3)编写AppForInstanceOrder运行类，在类中通过工厂获取对象</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">AppForInstanceOrder</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="comment">//通过静态工厂创建对象</span></span><br><span class="line">        <span class="type">OrderDao</span> <span class="variable">orderDao</span> <span class="operator">=</span> OrderDaoFactory.getOrderDao();</span><br><span class="line">        orderDao.save();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>(4)运行后，可以查看到结果</p>
<p><img src="/images/1629786862329.png"></p>
<p>如果代码中对象是通过上面的这种方式来创建的，如何将其交给Spring来管理呢?</p>
<h5 id="4-2-4-2-静态工厂实例化"><a href="#4-2-4-2-静态工厂实例化" class="headerlink" title="4.2.4.2 静态工厂实例化"></a>4.2.4.2 静态工厂实例化</h5><p>这就要用到Spring中的静态工厂实例化的知识了，具体实现步骤为:</p>
<p>(1)在spring的配置文件application.properties中添加以下内容:</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;orderDao&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.factory.OrderDaoFactory&quot;</span> <span class="attr">factory-method</span>=<span class="string">&quot;getOrderDao&quot;</span>/&gt;</span></span><br></pre></td></tr></table></figure>

<p>class:工厂类的类全名</p>
<p>factory-mehod:具体工厂类中创建对象的方法名</p>
<p>对应关系如下图:</p>
<p><img src="/images/image-20210729195248948.png"></p>
<p>(2)在AppForInstanceOrder运行类，使用从IOC容器中获取bean的方法进行运行测试</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">AppForInstanceOrder</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">ApplicationContext</span> <span class="variable">ctx</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ClassPathXmlApplicationContext</span>(<span class="string">&quot;applicationContext.xml&quot;</span>);</span><br><span class="line"></span><br><span class="line">        <span class="type">OrderDao</span> <span class="variable">orderDao</span> <span class="operator">=</span> (OrderDao) ctx.getBean(<span class="string">&quot;orderDao&quot;</span>);</span><br><span class="line"></span><br><span class="line">        orderDao.save();</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>(3)运行后，可以查看到结果</p>
<p><img src="/images/1629786862329.png"></p>
<p>看到这，可能有人会问了，你这种方式在工厂类中不也是直接new对象的，和我自己直接new没什么太大的区别，而且静态工厂的方式反而更复杂，这种方式的意义是什么?</p>
<p>主要的原因是:</p>
<ul>
<li>在工厂的静态方法中，我们除了new对象还可以做其他的一些业务操作，这些操作必不可少,如:</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">OrderDaoFactory</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> OrderDao <span class="title function_">getOrderDao</span><span class="params">()</span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;factory setup....&quot;</span>);<span class="comment">//模拟必要的业务操作</span></span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">OrderDaoImpl</span>();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>之前new对象的方式就无法添加其他的业务内容，重新运行，查看结果:</p>
<p><img src="/images/1629788036885.png"></p>
<p>介绍完静态工厂实例化后，这种方式一般是用来兼容早期的一些老系统，所以&#x3D;&#x3D;了解为主&#x3D;&#x3D;。</p>
<h4 id="4-2-5-实例工厂与FactoryBean"><a href="#4-2-5-实例工厂与FactoryBean" class="headerlink" title="4.2.5 实例工厂与FactoryBean"></a>4.2.5 实例工厂与FactoryBean</h4><p>接下来继续来研究Spring的第三种bean的创建方式<code>实例工厂实例化</code>:</p>
<h5 id="4-2-3-1-环境准备"><a href="#4-2-3-1-环境准备" class="headerlink" title="4.2.3.1 环境准备"></a>4.2.3.1 环境准备</h5><p>(1)准备一个UserDao和UserDaoImpl类</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">UserDao</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">UserDaoImpl</span> <span class="keyword">implements</span> <span class="title class_">UserDao</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;user dao save ...&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>(2)创建一个工厂类OrderDaoFactory并提供一个普通方法，注意此处和静态工厂的工厂类不一样的地方是方法不是静态方法</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">UserDaoFactory</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> UserDao <span class="title function_">getUserDao</span><span class="params">()</span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">UserDaoImpl</span>();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>(3)编写AppForInstanceUser运行类，在类中通过工厂获取对象</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">AppForInstanceUser</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="comment">//创建实例工厂对象</span></span><br><span class="line">        <span class="type">UserDaoFactory</span> <span class="variable">userDaoFactory</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">UserDaoFactory</span>();</span><br><span class="line">        <span class="comment">//通过实例工厂对象创建对象</span></span><br><span class="line">        <span class="type">UserDao</span> <span class="variable">userDao</span> <span class="operator">=</span> userDaoFactory.getUserDao();</span><br><span class="line">        userDao.save();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>(4)运行后，可以查看到结果</p>
<p><img src="/images/1629788769436.png"></p>
<p>对于上面这种实例工厂的方式如何交给Spring管理呢?</p>
<h5 id="4-2-3-2-实例工厂实例化"><a href="#4-2-3-2-实例工厂实例化" class="headerlink" title="4.2.3.2 实例工厂实例化"></a>4.2.3.2 实例工厂实例化</h5><p>具体实现步骤为:</p>
<p>(1)在spring的配置文件中添加以下内容:</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;userFactory&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.factory.UserDaoFactory&quot;</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;userDao&quot;</span> <span class="attr">factory-method</span>=<span class="string">&quot;getUserDao&quot;</span> <span class="attr">factory-bean</span>=<span class="string">&quot;userFactory&quot;</span>/&gt;</span></span><br></pre></td></tr></table></figure>

<p>实例化工厂运行的顺序是:</p>
<ul>
<li><p>创建实例化工厂对象,对应的是第一行配置</p>
</li>
<li><p>调用对象中的方法来创建bean，对应的是第二行配置</p>
<ul>
<li><p>factory-bean:工厂的实例对象</p>
</li>
<li><p>factory-method:工厂对象中的具体创建对象的方法名,对应关系如下:</p>
<p><img src="/images/image-20210729200203249.png"></p>
</li>
</ul>
</li>
</ul>
<p>factory-mehod:具体工厂类中创建对象的方法名</p>
<p>(2)在AppForInstanceUser运行类，使用从IOC容器中获取bean的方法进行运行测试</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">AppForInstanceUser</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">ApplicationContext</span> <span class="variable">ctx</span> <span class="operator">=</span> <span class="keyword">new</span> </span><br><span class="line">            <span class="title class_">ClassPathXmlApplicationContext</span>(<span class="string">&quot;applicationContext.xml&quot;</span>);</span><br><span class="line">        <span class="type">UserDao</span> <span class="variable">userDao</span> <span class="operator">=</span> (UserDao) ctx.getBean(<span class="string">&quot;userDao&quot;</span>);</span><br><span class="line">        userDao.save();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>(3)运行后，可以查看到结果</p>
<p><img src="/images/1629788769436.png"></p>
<p>实例工厂实例化的方式就已经介绍完了，配置的过程还是比较复杂，所以Spring为了简化这种配置方式就提供了一种叫<code>FactoryBean</code>的方式来简化开发。</p>
<h5 id="4-2-3-3-FactoryBean的使用"><a href="#4-2-3-3-FactoryBean的使用" class="headerlink" title="4.2.3.3 FactoryBean的使用"></a>4.2.3.3 FactoryBean的使用</h5><p>具体的使用步骤为:</p>
<p>(1)创建一个UserDaoFactoryBean的类，实现FactoryBean接口，重写接口的方法</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">UserDaoFactoryBean</span> <span class="keyword">implements</span> <span class="title class_">FactoryBean</span>&lt;UserDao&gt; &#123;</span><br><span class="line">    <span class="comment">//代替原始实例工厂中创建对象的方法</span></span><br><span class="line">    <span class="keyword">public</span> UserDao <span class="title function_">getObject</span><span class="params">()</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">UserDaoImpl</span>();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//返回所创建类的Class对象</span></span><br><span class="line">    <span class="keyword">public</span> Class&lt;?&gt; getObjectType() &#123;</span><br><span class="line">        <span class="keyword">return</span> UserDao.class;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>(2)在Spring的配置文件中进行配置</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;userDao&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.factory.UserDaoFactoryBean&quot;</span>/&gt;</span></span><br></pre></td></tr></table></figure>

<p>(3)AppForInstanceUser运行类不用做任何修改，直接运行</p>
<p><img src="/images/1629788769436.png"></p>
<p>这种方式在Spring去整合其他框架的时候会被用到，所以这种方式需要大家理解掌握。</p>
<p>查看源码会发现，FactoryBean接口其实会有三个方法，分别是:</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">T <span class="title function_">getObject</span><span class="params">()</span> <span class="keyword">throws</span> Exception;</span><br><span class="line"></span><br><span class="line">Class&lt;?&gt; getObjectType();</span><br><span class="line"></span><br><span class="line"><span class="keyword">default</span> <span class="type">boolean</span> <span class="title function_">isSingleton</span><span class="params">()</span> &#123;</span><br><span class="line">		<span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>方法一:getObject()，被重写后，在方法中进行对象的创建并返回</p>
<p>方法二:getObjectType(),被重写后，主要返回的是被创建类的Class对象</p>
<p>方法三:没有被重写，因为它已经给了默认值，从方法名中可以看出其作用是设置对象是否为单例，默认true，从意思上来看，我们猜想默认应该是单例，如何来验证呢?</p>
<p>思路很简单，就是从容器中获取该对象的多个值，打印到控制台，查看是否为同一个对象。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">AppForInstanceUser</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">ApplicationContext</span> <span class="variable">ctx</span> <span class="operator">=</span> <span class="keyword">new</span> </span><br><span class="line">            <span class="title class_">ClassPathXmlApplicationContext</span>(<span class="string">&quot;applicationContext.xml&quot;</span>);</span><br><span class="line">        <span class="type">UserDao</span> <span class="variable">userDao1</span> <span class="operator">=</span> (UserDao) ctx.getBean(<span class="string">&quot;userDao&quot;</span>);</span><br><span class="line">        <span class="type">UserDao</span> <span class="variable">userDao2</span> <span class="operator">=</span> (UserDao) ctx.getBean(<span class="string">&quot;userDao&quot;</span>);</span><br><span class="line">        System.out.println(userDao1);</span><br><span class="line">        System.out.println(userDao2);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>打印结果，如下:</p>
<p><img src="/images/1629790070607.png"></p>
<p>通过验证，会发现默认是单例，那如果想改成单例具体如何实现?</p>
<p>只需要将isSingleton()方法进行重写，修改返回为false，即可</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//FactoryBean创建对象</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">UserDaoFactoryBean</span> <span class="keyword">implements</span> <span class="title class_">FactoryBean</span>&lt;UserDao&gt; &#123;</span><br><span class="line">    <span class="comment">//代替原始实例工厂中创建对象的方法</span></span><br><span class="line">    <span class="keyword">public</span> UserDao <span class="title function_">getObject</span><span class="params">()</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">UserDaoImpl</span>();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> Class&lt;?&gt; getObjectType() &#123;</span><br><span class="line">        <span class="keyword">return</span> UserDao.class;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">isSingleton</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>重新运行AppForInstanceUser，查看结果</p>
<p><img src="/images/1629790197860.png"></p>
<p>从结果中可以看出现在已经是非单例了，但是一般情况下我们都会采用单例，也就是采用默认即可。所以isSingleton()方法一般不需要进行重写。</p>
<h4 id="4-2-6-bean实例化小结"><a href="#4-2-6-bean实例化小结" class="headerlink" title="4.2.6 bean实例化小结"></a>4.2.6 bean实例化小结</h4><p>通过这一节的学习，需要掌握:</p>
<p>(1)bean是如何创建的呢?</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">构造方法</span><br></pre></td></tr></table></figure>

<p>(2)Spring的IOC实例化对象的三种方式分别是:</p>
<ul>
<li>构造方法(常用)</li>
<li>静态工厂(了解)</li>
<li>实例工厂(了解)<ul>
<li>FactoryBean(实用)</li>
</ul>
</li>
</ul>
<p>这些方式中，重点掌握<code>构造方法</code>和<code>FactoryBean</code>即可。</p>
<p>需要注意的一点是，构造方法在类中默认会提供，但是如果重写了构造方法，默认的就会消失，在使用的过程中需要注意，如果需要重写构造方法，最好把默认的构造方法也重写下。</p>
<h3 id="4-3-bean的生命周期"><a href="#4-3-bean的生命周期" class="headerlink" title="4.3 bean的生命周期"></a>4.3 bean的生命周期</h3><p>关于bean的相关知识还有最后一个是<code>bean的生命周期</code>,对于生命周期，我们主要围绕着<code>bean生命周期控制</code>来讲解:</p>
<ul>
<li>首先理解下什么是生命周期?<ul>
<li>从创建到消亡的完整过程,例如人<strong>从出生到死亡</strong>的整个过程就是一个生命周期。</li>
</ul>
</li>
<li>bean生命周期是什么?<ul>
<li>bean对象从创建到销毁的整体过程。</li>
</ul>
</li>
<li>bean生命周期控制是什么?<ul>
<li>在bean创建后到销毁前做一些事情。</li>
</ul>
</li>
</ul>
<p>现在我们面临的问题是如何在bean的创建之后和销毁之前把我们需要添加的内容添加进去。</p>
<h4 id="4-3-1-环境准备"><a href="#4-3-1-环境准备" class="headerlink" title="4.3.1 环境准备"></a>4.3.1 环境准备</h4><p>还是老规矩，为了方便大家后期代码的阅读，我们重新搭建下环境:</p>
<ul>
<li>创建一个Maven项目</li>
<li>pom.xml添加依赖</li>
<li>resources下添加spring的配置文件applicationContext.xml</li>
</ul>
<p>这些步骤和前面的都一致，大家可以快速的拷贝即可，最终项目的结构如下:</p>
<p><img src="/images/1629791473409.png"></p>
<p>(1)项目中添加BookDao、BookDaoImpl、BookService和BookServiceImpl类</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">BookDao</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">BookDaoImpl</span> <span class="keyword">implements</span> <span class="title class_">BookDao</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;book dao save ...&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">BookService</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">BookServiceImpl</span> <span class="keyword">implements</span> <span class="title class_">BookService</span>&#123;</span><br><span class="line">    <span class="keyword">private</span> BookDao bookDao;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setBookDao</span><span class="params">(BookDao bookDao)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.bookDao = bookDao;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;book service save ...&quot;</span>);</span><br><span class="line">        bookDao.save();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>(2)resources下提供spring的配置文件</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version=<span class="string">&quot;1.0&quot;</span> encoding=<span class="string">&quot;UTF-8&quot;</span>?&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">beans</span> <span class="attr">xmlns</span>=<span class="string">&quot;http://www.springframework.org/schema/beans&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:xsi</span>=<span class="string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xsi:schemaLocation</span>=<span class="string">&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd&quot;</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;bookDao&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.dao.impl.BookDaoImpl&quot;</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">beans</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p>(3)编写AppForLifeCycle运行类，加载Spring的IOC容器，并从中获取对应的bean对象</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">AppForLifeCycle</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">( String[] args )</span> &#123;</span><br><span class="line">        <span class="type">ApplicationContext</span> <span class="variable">ctx</span> <span class="operator">=</span> <span class="keyword">new</span> </span><br><span class="line">        	<span class="title class_">ClassPathXmlApplicationContext</span>(<span class="string">&quot;applicationContext.xml&quot;</span>);</span><br><span class="line">        <span class="type">BookDao</span> <span class="variable">bookDao</span> <span class="operator">=</span> (BookDao) ctx.getBean(<span class="string">&quot;bookDao&quot;</span>);</span><br><span class="line">        bookDao.save();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h4 id="4-3-2-生命周期设置"><a href="#4-3-2-生命周期设置" class="headerlink" title="4.3.2 生命周期设置"></a>4.3.2 生命周期设置</h4><p>接下来，在上面这个环境中来为BookDao添加生命周期的控制方法，具体的控制有两个阶段:</p>
<ul>
<li>bean<strong>创建之后</strong>，想要添加内容，比如用<strong>来初始化需要用到资源</strong></li>
<li>bean销毁之前，想要添加内容，比如用来释放用到的资源</li>
</ul>
<h5 id="步骤1-添加初始化和销毁方法"><a href="#步骤1-添加初始化和销毁方法" class="headerlink" title="步骤1:添加初始化和销毁方法"></a>步骤1:添加初始化和销毁方法</h5><p>针对这两个阶段，我们在BooDaoImpl类中分别添加两个方法，&#x3D;&#x3D;方法名任意&#x3D;&#x3D;</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">BookDaoImpl</span> <span class="keyword">implements</span> <span class="title class_">BookDao</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;book dao save ...&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//表示bean初始化对应的操作</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">init</span><span class="params">()</span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;init...&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//表示bean销毁前对应的操作</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">destory</span><span class="params">()</span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;destory...&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h5 id="步骤2-配置生命周期"><a href="#步骤2-配置生命周期" class="headerlink" title="步骤2:配置生命周期"></a>步骤2:配置生命周期</h5><p>在配置文件添加配置，如下:</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;bookDao&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.dao.impl.BookDaoImpl&quot;</span> <span class="attr">init-method</span>=<span class="string">&quot;init&quot;</span> <span class="attr">destroy-method</span>=<span class="string">&quot;destory&quot;</span>/&gt;</span></span><br></pre></td></tr></table></figure>

<h5 id="步骤3-运行程序-1"><a href="#步骤3-运行程序-1" class="headerlink" title="步骤3:运行程序"></a>步骤3:运行程序</h5><p>运行AppForLifeCycle打印结果为:</p>
<p><img src="/images/1629792339889.png"></p>
<p>从结果中可以看出，init方法执行了，但是destroy方法却未执行，这是为什么呢?</p>
<ul>
<li>Spring的IOC容器是运行在JVM中</li>
<li>运行main方法后,JVM启动,Spring加载配置文件生成IOC容器,从容器获取bean对象，然后调方法执行</li>
<li>main方法执行完后，JVM退出，这个时候IOC容器中的bean还没有来得及销毁就已经结束了</li>
<li>所以没有调用对应的destroy方法</li>
</ul>
<p>知道了出现问题的原因，具体该如何解决呢?</p>
<h4 id="4-3-3-close关闭容器"><a href="#4-3-3-close关闭容器" class="headerlink" title="4.3.3 close关闭容器"></a>4.3.3 close关闭容器</h4><ul>
<li><p>ApplicationContext中没有close方法</p>
</li>
<li><p>需要将ApplicationContext更换成ClassPathXmlApplicationContext</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">ClassPathXmlApplicationContext</span> <span class="variable">ctx</span> <span class="operator">=</span> <span class="keyword">new</span> </span><br><span class="line">    <span class="title class_">ClassPathXmlApplicationContext</span>(<span class="string">&quot;applicationContext.xml&quot;</span>);</span><br></pre></td></tr></table></figure>
</li>
<li><p>调用ctx的close()方法</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ctx.close();</span><br></pre></td></tr></table></figure>
</li>
<li><p>运行程序，就能执行destroy方法的内容</p>
<p><img src="/images/1629792857608.png"></p>
</li>
</ul>
<h4 id="4-3-4-注册钩子关闭容器"><a href="#4-3-4-注册钩子关闭容器" class="headerlink" title="4.3.4 注册钩子关闭容器"></a>4.3.4 注册钩子关闭容器</h4><ul>
<li><p>在容器未关闭之前，提前设置好回调函数，让JVM在退出之前回调此函数来关闭容器</p>
</li>
<li><p>调用ctx的<code>registerShutdownHook()</code>方法</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ctx.registerShutdownHook();</span><br></pre></td></tr></table></figure>

<p>**注意:**registerShutdownHook在ApplicationContext中也没有</p>
</li>
<li><p>运行后，查询打印结果</p>
<p><img src="/images/1629792857608.png"></p>
</li>
</ul>
<p>两种方式介绍完后，close和registerShutdownHook选哪个?</p>
<p>相同点:这两种都能用来关闭容器</p>
<p>不同点:close()是在调用的时候关闭，registerShutdownHook()是在JVM退出前调用关闭。</p>
<p>分析上面的实现过程，会发现添加初始化和销毁方法，即需要编码也需要配置，实现起来步骤比较多也比较乱。</p>
<p>Spring提供了两个接口来完成生命周期的控制，好处是可以不用再进行配置<code>init-method</code>和<code>destroy-method</code></p>
<p>接下来在BookServiceImpl完成这两个接口的使用:</p>
<p>修改BookServiceImpl类，添加两个接口<code>InitializingBean</code>， <code>DisposableBean</code>并实现接口中的两个方法<code>afterPropertiesSet</code>和<code>destroy</code></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">BookServiceImpl</span> <span class="keyword">implements</span> <span class="title class_">BookService</span>, InitializingBean, DisposableBean &#123;</span><br><span class="line">    <span class="keyword">private</span> BookDao bookDao;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setBookDao</span><span class="params">(BookDao bookDao)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.bookDao = bookDao;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;book service save ...&quot;</span>);</span><br><span class="line">        bookDao.save(); </span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">destroy</span><span class="params">()</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;service destroy&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">afterPropertiesSet</span><span class="params">()</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;service init&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>重新运行AppForLifeCycle类，</p>
<p><img src="/images/1629794527419.png"></p>
<p>那第二种方式的实现，我们也介绍完了。</p>
<p><strong>小细节</strong></p>
<ul>
<li><p>对于InitializingBean接口中的afterPropertiesSet方法，翻译过来为<code>属性设置之后</code>。</p>
</li>
<li><p>对于BookServiceImpl来说，bookDao是它的一个属性</p>
</li>
<li><p>setBookDao方法是Spring的IOC容器为其注入属性的方法</p>
</li>
<li><p>思考:afterPropertiesSet和setBookDao谁先执行?</p>
<ul>
<li><p>从方法名分析，猜想应该是setBookDao方法先执行</p>
</li>
<li><p>验证思路，在setBookDao方法中添加一句话</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setBookDao</span><span class="params">(BookDao bookDao)</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;set .....&quot;</span>);</span><br><span class="line">        <span class="built_in">this</span>.bookDao = bookDao;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>
</li>
<li><p>重新运行AppForLifeCycle，打印结果如下:</p>
<p><img src="/images/1629794928636.png"></p>
<p>验证的结果和我们猜想的结果是一致的，所以初始化方法会在类中属性设置之后执行。</p>
</li>
</ul>
</li>
</ul>
<h4 id="4-3-5-bean生命周期小结"><a href="#4-3-5-bean生命周期小结" class="headerlink" title="4.3.5 bean生命周期小结"></a>4.3.5 bean生命周期小结</h4><p>(1)关于Spring中对bean生命周期控制提供了两种方式:</p>
<ul>
<li>在配置文件中的bean标签中添加<code>init-method</code>和<code>destroy-method</code>属性</li>
<li>类实现<code>InitializingBean</code>与<code>DisposableBean</code>接口，这种方式了解下即可。</li>
</ul>
<p>(2)对于bean的生命周期控制在bean的整个生命周期中所处的位置如下:</p>
<ul>
<li>初始化容器<ul>
<li>1.创建对象(内存分配)</li>
<li>2.执行构造方法</li>
<li>3.执行属性注入(set操作)</li>
<li>&#x3D;&#x3D;4.执行bean初始化方法&#x3D;&#x3D;</li>
</ul>
</li>
<li>使用bean<ul>
<li>1.执行业务操作</li>
</ul>
</li>
<li>关闭&#x2F;销毁容器<ul>
<li>&#x3D;&#x3D;1.执行bean销毁方法&#x3D;&#x3D;</li>
</ul>
</li>
</ul>
<p>(3)关闭容器的两种方式:</p>
<ul>
<li>ConfigurableApplicationContext是ApplicationContext的子类<ul>
<li>close()方法</li>
<li>registerShutdownHook()方法</li>
</ul>
</li>
</ul>
<h2 id="5，DI相关内容"><a href="#5，DI相关内容" class="headerlink" title="5，DI相关内容"></a>5，DI相关内容</h2><p>前面我们已经完成了bean相关操作的讲解，接下来就进入第二个大的模块<code>DI依赖注入</code>，首先来介绍下Spring中有哪些注入方式?</p>
<p>我们先来思考</p>
<ul>
<li>向一个类中传递数据的方式有几种?<ul>
<li>普通方法(set方法)</li>
<li>构造方法</li>
</ul>
</li>
<li>依赖注入描述了在容器中建立bean与bean之间的依赖关系的过程，如果bean运行需要的是数字或字符串呢?<ul>
<li>引用类型</li>
<li>简单类型(基本数据类型与String)</li>
</ul>
</li>
</ul>
<p>Spring就是基于上面这些知识点，为我们提供了两种注入方式，分别是:</p>
<ul>
<li>setter注入<ul>
<li>简单类型</li>
<li>&#x3D;&#x3D;引用类型&#x3D;&#x3D;</li>
</ul>
</li>
<li>构造器注入<ul>
<li>简单类型</li>
<li>引用类型</li>
</ul>
</li>
</ul>
<p>依赖注入的方式已经介绍完，接下来挨个学习下:</p>
<h3 id="5-1-setter注入"><a href="#5-1-setter注入" class="headerlink" title="5.1 setter注入"></a>5.1 setter注入</h3><ol>
<li>对于setter方式注入引用类型的方式之前已经学习过，快速回顾下:</li>
</ol>
<ul>
<li>在bean中定义引用类型属性，并提供可访问的&#x3D;&#x3D;set&#x3D;&#x3D;方法</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">BookServiceImpl</span> <span class="keyword">implements</span> <span class="title class_">BookService</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> BookDao bookDao;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setBookDao</span><span class="params">(BookDao bookDao)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.bookDao = bookDao;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<ul>
<li>配置中使用&#x3D;&#x3D;property&#x3D;&#x3D;标签&#x3D;&#x3D;ref&#x3D;&#x3D;属性注入引用类型对象</li>
</ul>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;bookService&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.service.impl.BookServiceImpl&quot;</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;bookDao&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;bookDao&quot;</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;bookDao&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.dao.imipl.BookDaoImpl&quot;</span>/&gt;</span></span><br></pre></td></tr></table></figure>

<h4 id="5-1-1-环境准备"><a href="#5-1-1-环境准备" class="headerlink" title="5.1.1 环境准备"></a>5.1.1 环境准备</h4><p>为了更好的学习下面内容，我们依旧准备一个新环境:</p>
<ul>
<li>创建一个Maven项目</li>
<li>pom.xml添加依赖</li>
<li>resources下添加spring的配置文件</li>
</ul>
<p>这些步骤和前面的都一致，大家可以快速的拷贝即可，最终项目的结构如下:</p>
<p><img src="/images/1629799214191.png"></p>
<p>(1)项目中添加BookDao、BookDaoImpl、UserDao、UserDaoImpl、BookService和BookServiceImpl类</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">BookDao</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">BookDaoImpl</span> <span class="keyword">implements</span> <span class="title class_">BookDao</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;book dao save ...&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">UserDao</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">UserDaoImpl</span> <span class="keyword">implements</span> <span class="title class_">UserDao</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;user dao save ...&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">BookService</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">BookServiceImpl</span> <span class="keyword">implements</span> <span class="title class_">BookService</span>&#123;</span><br><span class="line">    <span class="keyword">private</span> BookDao bookDao;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setBookDao</span><span class="params">(BookDao bookDao)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.bookDao = bookDao;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;book service save ...&quot;</span>);</span><br><span class="line">        bookDao.save();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>(2)resources下提供spring的配置文件</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version=<span class="string">&quot;1.0&quot;</span> encoding=<span class="string">&quot;UTF-8&quot;</span>?&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">beans</span> <span class="attr">xmlns</span>=<span class="string">&quot;http://www.springframework.org/schema/beans&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:xsi</span>=<span class="string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xsi:schemaLocation</span>=<span class="string">&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd&quot;</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;bookDao&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.dao.impl.BookDaoImpl&quot;</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;bookService&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.service.impl.BookServiceImpl&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;bookDao&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;bookDao&quot;</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">beans</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p>(3)编写AppForDISet运行类，加载Spring的IOC容器，并从中获取对应的bean对象</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">AppForDISet</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">( String[] args )</span> &#123;</span><br><span class="line">        <span class="type">ApplicationContext</span> <span class="variable">ctx</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ClassPathXmlApplicationContext</span>(<span class="string">&quot;applicationContext.xml&quot;</span>);</span><br><span class="line">        <span class="type">BookService</span> <span class="variable">bookService</span> <span class="operator">=</span> (BookService) ctx.getBean(<span class="string">&quot;bookService&quot;</span>);</span><br><span class="line">        bookService.save();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>接下来，在上面这个环境中来完成setter注入的学习:</p>
<h4 id="5-1-2-注入引用数据类型"><a href="#5-1-2-注入引用数据类型" class="headerlink" title="5.1.2 注入引用数据类型"></a>5.1.2 注入引用数据类型</h4><blockquote>
<p>需求:在bookServiceImpl对象中注入userDao</p>
<p>1.在BookServiceImpl中声明userDao属性</p>
<p>2.为userDao属性提供setter方法</p>
<p>3.在配置文件中使用property标签注入</p>
</blockquote>
<h5 id="步骤1-声明属性并提供setter方法"><a href="#步骤1-声明属性并提供setter方法" class="headerlink" title="步骤1:声明属性并提供setter方法"></a>步骤1:声明属性并提供setter方法</h5><p>在BookServiceImpl中声明userDao属性，并提供setter方法</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">BookServiceImpl</span> <span class="keyword">implements</span> <span class="title class_">BookService</span>&#123;</span><br><span class="line">    <span class="keyword">private</span> BookDao bookDao;</span><br><span class="line">    <span class="keyword">private</span> UserDao userDao;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setUserDao</span><span class="params">(UserDao userDao)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.userDao = userDao;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setBookDao</span><span class="params">(BookDao bookDao)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.bookDao = bookDao;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;book service save ...&quot;</span>);</span><br><span class="line">        bookDao.save();</span><br><span class="line">        userDao.save();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h5 id="步骤2-配置文件中进行注入配置"><a href="#步骤2-配置文件中进行注入配置" class="headerlink" title="步骤2:配置文件中进行注入配置"></a>步骤2:配置文件中进行注入配置</h5><p>在applicationContext.xml配置文件中使用property标签注入</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version=<span class="string">&quot;1.0&quot;</span> encoding=<span class="string">&quot;UTF-8&quot;</span>?&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">beans</span> <span class="attr">xmlns</span>=<span class="string">&quot;http://www.springframework.org/schema/beans&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:xsi</span>=<span class="string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xsi:schemaLocation</span>=<span class="string">&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd&quot;</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;bookDao&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.dao.impl.BookDaoImpl&quot;</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;userDao&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.dao.impl.UserDaoImpl&quot;</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;bookService&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.service.impl.BookServiceImpl&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;bookDao&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;bookDao&quot;</span>/&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;userDao&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;userDao&quot;</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">beans</span>&gt;</span></span><br></pre></td></tr></table></figure>

<h5 id="步骤3-运行程序-2"><a href="#步骤3-运行程序-2" class="headerlink" title="步骤3:运行程序"></a>步骤3:运行程序</h5><p>运行AppForDISet类，查看结果，说明userDao已经成功注入。</p>
<p><img src="/images/1629799873386.png"></p>
<h4 id="5-1-3-注入简单数据类型"><a href="#5-1-3-注入简单数据类型" class="headerlink" title="5.1.3 注入简单数据类型"></a>5.1.3 注入简单数据类型</h4><blockquote>
<p>需求：给BookDaoImpl注入一些简单数据类型的数据</p>
<p>参考引用数据类型的注入，我们可以推出具体的步骤为:</p>
<p>1.在BookDaoImpl类中声明对应的简单数据类型的属性</p>
<p>2.为这些属性提供对应的setter方法</p>
<p>3.在applicationContext.xml中配置</p>
</blockquote>
<p><strong>思考:</strong></p>
<p>引用类型使用的是<code>&lt;property name=&quot;&quot; ref=&quot;&quot;/&gt;</code>,简单数据类型还是使用ref么?</p>
<p>ref是指向Spring的IOC容器中的另一个bean对象的，对于简单数据类型，没有对应的bean对象，该如何配置?</p>
<h5 id="步骤1-声明属性并提供setter方法-1"><a href="#步骤1-声明属性并提供setter方法-1" class="headerlink" title="步骤1:声明属性并提供setter方法"></a>步骤1:声明属性并提供setter方法</h5><p>在BookDaoImpl类中声明对应的简单数据类型的属性,并提供对应的setter方法</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">BookDaoImpl</span> <span class="keyword">implements</span> <span class="title class_">BookDao</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> String databaseName;</span><br><span class="line">    <span class="keyword">private</span> <span class="type">int</span> connectionNum;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setConnectionNum</span><span class="params">(<span class="type">int</span> connectionNum)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.connectionNum = connectionNum;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setDatabaseName</span><span class="params">(String databaseName)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.databaseName = databaseName;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;book dao save ...&quot;</span>+databaseName+<span class="string">&quot;,&quot;</span>+connectionNum);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h5 id="步骤2-配置文件中进行注入配置-1"><a href="#步骤2-配置文件中进行注入配置-1" class="headerlink" title="步骤2:配置文件中进行注入配置"></a>步骤2:配置文件中进行注入配置</h5><p>在applicationContext.xml配置文件中使用property标签注入</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version=<span class="string">&quot;1.0&quot;</span> encoding=<span class="string">&quot;UTF-8&quot;</span>?&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">beans</span> <span class="attr">xmlns</span>=<span class="string">&quot;http://www.springframework.org/schema/beans&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:xsi</span>=<span class="string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xsi:schemaLocation</span>=<span class="string">&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd&quot;</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;bookDao&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.dao.impl.BookDaoImpl&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;databaseName&quot;</span> <span class="attr">value</span>=<span class="string">&quot;mysql&quot;</span>/&gt;</span></span><br><span class="line">     	<span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;connectionNum&quot;</span> <span class="attr">value</span>=<span class="string">&quot;10&quot;</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;userDao&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.dao.impl.UserDaoImpl&quot;</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;bookService&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.service.impl.BookServiceImpl&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;bookDao&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;bookDao&quot;</span>/&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;userDao&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;userDao&quot;</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">beans</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p><strong>说明:</strong></p>
<p>value:后面跟的是简单数据类型，对于参数类型，Spring在注入的时候会自动转换，但是不能写成</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;connectionNum&quot;</span> <span class="attr">value</span>=<span class="string">&quot;abc&quot;</span>/&gt;</span></span><br></pre></td></tr></table></figure>

<p>这样的话，spring在将<code>abc</code>转换成int类型的时候就会报错。</p>
<h5 id="步骤3-运行程序-3"><a href="#步骤3-运行程序-3" class="headerlink" title="步骤3:运行程序"></a>步骤3:运行程序</h5><p>运行AppForDISet类，查看结果，说明userDao已经成功注入。</p>
<p><img src="/images/1629800324721.png"></p>
<p>**注意:**两个property注入标签的顺序可以任意。</p>
<p>对于setter注入方式的基本使用就已经介绍完了，</p>
<ul>
<li>对于引用数据类型使用的是<code>&lt;property name=&quot;&quot; ref=&quot;&quot;/&gt;</code></li>
<li>对于简单数据类型使用的是<code>&lt;property name=&quot;&quot; value=&quot;&quot;/&gt;</code></li>
</ul>
<h3 id="5-2-构造器注入"><a href="#5-2-构造器注入" class="headerlink" title="5.2 构造器注入"></a>5.2 构造器注入</h3><h4 id="5-2-1-环境准备"><a href="#5-2-1-环境准备" class="headerlink" title="5.2.1 环境准备"></a>5.2.1 环境准备</h4><p>构造器注入也就是构造方法注入，学习之前，还是先准备下环境:</p>
<ul>
<li>创建一个Maven项目</li>
<li>pom.xml添加依赖</li>
<li>resources下添加spring的配置文件</li>
</ul>
<p>这些步骤和前面的都一致，大家可以快速的拷贝即可，最终项目的结构如下:</p>
<p><img src="/images/1629800748639.png"></p>
<p>(1)项目中添加BookDao、BookDaoImpl、UserDao、UserDaoImpl、BookService和BookServiceImpl类</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">BookDao</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">BookDaoImpl</span> <span class="keyword">implements</span> <span class="title class_">BookDao</span> &#123;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">private</span> String databaseName;</span><br><span class="line">    <span class="keyword">private</span> <span class="type">int</span> connectionNum;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;book dao save ...&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">UserDao</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">UserDaoImpl</span> <span class="keyword">implements</span> <span class="title class_">UserDao</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;user dao save ...&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">BookService</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">BookServiceImpl</span> <span class="keyword">implements</span> <span class="title class_">BookService</span>&#123;</span><br><span class="line">    <span class="keyword">private</span> BookDao bookDao;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setBookDao</span><span class="params">(BookDao bookDao)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.bookDao = bookDao;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;book service save ...&quot;</span>);</span><br><span class="line">        bookDao.save();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>(2)resources下提供spring的配置文件</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version=<span class="string">&quot;1.0&quot;</span> encoding=<span class="string">&quot;UTF-8&quot;</span>?&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">beans</span> <span class="attr">xmlns</span>=<span class="string">&quot;http://www.springframework.org/schema/beans&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:xsi</span>=<span class="string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xsi:schemaLocation</span>=<span class="string">&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd&quot;</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;bookDao&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.dao.impl.BookDaoImpl&quot;</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;bookService&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.service.impl.BookServiceImpl&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;bookDao&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;bookDao&quot;</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">beans</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p>(3)编写AppForDIConstructor运行类，加载Spring的IOC容器，并从中获取对应的bean对象</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">AppForDIConstructor</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">( String[] args )</span> &#123;</span><br><span class="line">        <span class="type">ApplicationContext</span> <span class="variable">ctx</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ClassPathXmlApplicationContext</span>(<span class="string">&quot;applicationContext.xml&quot;</span>);</span><br><span class="line">        <span class="type">BookService</span> <span class="variable">bookService</span> <span class="operator">=</span> (BookService) ctx.getBean(<span class="string">&quot;bookService&quot;</span>);</span><br><span class="line">        bookService.save();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h4 id="5-2-2-构造器注入引用数据类型"><a href="#5-2-2-构造器注入引用数据类型" class="headerlink" title="5.2.2 构造器注入引用数据类型"></a>5.2.2 构造器注入引用数据类型</h4><p>接下来，在上面这个环境中来完成构造器注入的学习:</p>
<blockquote>
<p>需求：将BookServiceImpl类中的bookDao修改成使用构造器的方式注入。</p>
<p>1.将bookDao的setter方法删除掉</p>
<p>2.添加带有bookDao参数的构造方法</p>
<p>3.在applicationContext.xml中配置</p>
</blockquote>
<h5 id="步骤1-删除setter方法并提供构造方法"><a href="#步骤1-删除setter方法并提供构造方法" class="headerlink" title="步骤1:删除setter方法并提供构造方法"></a>步骤1:删除setter方法并提供构造方法</h5><p>在BookServiceImpl类中将bookDao的setter方法删除掉,并添加带有bookDao参数的构造方法</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">BookServiceImpl</span> <span class="keyword">implements</span> <span class="title class_">BookService</span>&#123;</span><br><span class="line">    <span class="keyword">private</span> BookDao bookDao;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">BookServiceImpl</span><span class="params">(BookDao bookDao)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.bookDao = bookDao;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;book service save ...&quot;</span>);</span><br><span class="line">        bookDao.save();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h5 id="步骤2-配置文件中进行配置构造方式注入"><a href="#步骤2-配置文件中进行配置构造方式注入" class="headerlink" title="步骤2:配置文件中进行配置构造方式注入"></a>步骤2:配置文件中进行配置构造方式注入</h5><p>在applicationContext.xml中配置</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version=<span class="string">&quot;1.0&quot;</span> encoding=<span class="string">&quot;UTF-8&quot;</span>?&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">beans</span> <span class="attr">xmlns</span>=<span class="string">&quot;http://www.springframework.org/schema/beans&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:xsi</span>=<span class="string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xsi:schemaLocation</span>=<span class="string">&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd&quot;</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;bookDao&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.dao.impl.BookDaoImpl&quot;</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;bookService&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.service.impl.BookServiceImpl&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">constructor-arg</span> <span class="attr">name</span>=<span class="string">&quot;bookDao&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;bookDao&quot;</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">beans</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p><strong>说明:</strong></p>
<p>标签<constructor-arg>中</p>
<ul>
<li><p>name属性对应的值为构造函数中方法形参的参数名，必须要保持一致。</p>
</li>
<li><p>ref属性指向的是spring的IOC容器中其他bean对象。</p>
</li>
</ul>
<h5 id="步骤3：运行程序"><a href="#步骤3：运行程序" class="headerlink" title="步骤3：运行程序"></a>步骤3：运行程序</h5><p>运行AppForDIConstructor类，查看结果，说明bookDao已经成功注入。</p>
<p><img src="/images/1629802656916.png"></p>
<h4 id="5-2-3-构造器注入多个引用数据类型"><a href="#5-2-3-构造器注入多个引用数据类型" class="headerlink" title="5.2.3 构造器注入多个引用数据类型"></a>5.2.3 构造器注入多个引用数据类型</h4><blockquote>
<p>需求:在BookServiceImpl使用构造函数注入多个引用数据类型，比如userDao</p>
<p>1.声明userDao属性</p>
<p>2.生成一个带有bookDao和userDao参数的构造函数</p>
<p>3.在applicationContext.xml中配置注入</p>
</blockquote>
<h5 id="步骤1-提供多个属性的构造函数"><a href="#步骤1-提供多个属性的构造函数" class="headerlink" title="步骤1:提供多个属性的构造函数"></a>步骤1:提供多个属性的构造函数</h5><p>在BookServiceImpl声明userDao并提供多个参数的构造函数</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">BookServiceImpl</span> <span class="keyword">implements</span> <span class="title class_">BookService</span>&#123;</span><br><span class="line">    <span class="keyword">private</span> BookDao bookDao;</span><br><span class="line">    <span class="keyword">private</span> UserDao userDao;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">BookServiceImpl</span><span class="params">(BookDao bookDao,UserDao userDao)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.bookDao = bookDao;</span><br><span class="line">        <span class="built_in">this</span>.userDao = userDao;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;book service save ...&quot;</span>);</span><br><span class="line">        bookDao.save();</span><br><span class="line">        userDao.save();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>步骤2:配置文件中配置多参数注入</p>
<p>在applicationContext.xml中配置注入</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version=<span class="string">&quot;1.0&quot;</span> encoding=<span class="string">&quot;UTF-8&quot;</span>?&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">beans</span> <span class="attr">xmlns</span>=<span class="string">&quot;http://www.springframework.org/schema/beans&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:xsi</span>=<span class="string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xsi:schemaLocation</span>=<span class="string">&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd&quot;</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;bookDao&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.dao.impl.BookDaoImpl&quot;</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;userDao&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.dao.impl.UserDaoImpl&quot;</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;bookService&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.service.impl.BookServiceImpl&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">constructor-arg</span> <span class="attr">name</span>=<span class="string">&quot;bookDao&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;bookDao&quot;</span>/&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">constructor-arg</span> <span class="attr">name</span>=<span class="string">&quot;userDao&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;userDao&quot;</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">beans</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p>**说明:**这两个<code>&lt;contructor-arg&gt;</code>的配置顺序可以任意</p>
<h5 id="步骤3-运行程序-4"><a href="#步骤3-运行程序-4" class="headerlink" title="步骤3:运行程序"></a>步骤3:运行程序</h5><p>运行AppForDIConstructor类，查看结果，说明userDao已经成功注入。</p>
<p><img src="/images/1629802697318.png"></p>
<h4 id="5-2-4-构造器注入多个简单数据类型"><a href="#5-2-4-构造器注入多个简单数据类型" class="headerlink" title="5.2.4 构造器注入多个简单数据类型"></a>5.2.4 构造器注入多个简单数据类型</h4><blockquote>
<p>需求:在BookDaoImpl中，使用构造函数注入databaseName和connectionNum两个参数。</p>
<p>参考引用数据类型的注入，我们可以推出具体的步骤为:</p>
<p>1.提供一个包含这两个参数的构造方法</p>
<p>2.在applicationContext.xml中进行注入配置</p>
</blockquote>
<h5 id="步骤1-添加多个简单属性并提供构造方法"><a href="#步骤1-添加多个简单属性并提供构造方法" class="headerlink" title="步骤1:添加多个简单属性并提供构造方法"></a>步骤1:添加多个简单属性并提供构造方法</h5><p>修改BookDaoImpl类，添加构造方法</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">BookDaoImpl</span> <span class="keyword">implements</span> <span class="title class_">BookDao</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> String databaseName;</span><br><span class="line">    <span class="keyword">private</span> <span class="type">int</span> connectionNum;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">BookDaoImpl</span><span class="params">(String databaseName, <span class="type">int</span> connectionNum)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.databaseName = databaseName;</span><br><span class="line">        <span class="built_in">this</span>.connectionNum = connectionNum;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;book dao save ...&quot;</span>+databaseName+<span class="string">&quot;,&quot;</span>+connectionNum);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h5 id="步骤2-配置完成多个属性构造器注入"><a href="#步骤2-配置完成多个属性构造器注入" class="headerlink" title="步骤2:配置完成多个属性构造器注入"></a>步骤2:配置完成多个属性构造器注入</h5><p>在applicationContext.xml中进行注入配置</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version=<span class="string">&quot;1.0&quot;</span> encoding=<span class="string">&quot;UTF-8&quot;</span>?&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">beans</span> <span class="attr">xmlns</span>=<span class="string">&quot;http://www.springframework.org/schema/beans&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:xsi</span>=<span class="string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xsi:schemaLocation</span>=<span class="string">&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd&quot;</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;bookDao&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.dao.impl.BookDaoImpl&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">constructor-arg</span> <span class="attr">name</span>=<span class="string">&quot;databaseName&quot;</span> <span class="attr">value</span>=<span class="string">&quot;mysql&quot;</span>/&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">constructor-arg</span> <span class="attr">name</span>=<span class="string">&quot;connectionNum&quot;</span> <span class="attr">value</span>=<span class="string">&quot;666&quot;</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;userDao&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.dao.impl.UserDaoImpl&quot;</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;bookService&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.service.impl.BookServiceImpl&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">constructor-arg</span> <span class="attr">name</span>=<span class="string">&quot;bookDao&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;bookDao&quot;</span>/&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">constructor-arg</span> <span class="attr">name</span>=<span class="string">&quot;userDao&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;userDao&quot;</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">beans</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p>**说明:**这两个<code>&lt;contructor-arg&gt;</code>的配置顺序可以任意</p>
<h5 id="步骤3-运行程序-5"><a href="#步骤3-运行程序-5" class="headerlink" title="步骤3:运行程序"></a>步骤3:运行程序</h5><p>运行AppForDIConstructor类，查看结果</p>
<p><img src="/images/1629803111769.png"></p>
<p>上面已经完成了构造函数注入的基本使用，但是会存在一些问题:</p>
<p><img src="/images/1629803529598.png"></p>
<ul>
<li>当构造函数中方法的参数名发生变化后，配置文件中的name属性也需要跟着变</li>
<li>这两块存在紧耦合，具体该如何解决?</li>
</ul>
<p>在解决这个问题之前，需要提前说明的是，这个参数名发生变化的情况并不多，所以上面的还是比较主流的配置方式，下面介绍的，大家都以了解为主。</p>
<p>方式一:删除name属性，添加type属性，按照类型注入</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;bookDao&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.dao.impl.BookDaoImpl&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">constructor-arg</span> <span class="attr">type</span>=<span class="string">&quot;int&quot;</span> <span class="attr">value</span>=<span class="string">&quot;10&quot;</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">constructor-arg</span> <span class="attr">type</span>=<span class="string">&quot;java.lang.String&quot;</span> <span class="attr">value</span>=<span class="string">&quot;mysql&quot;</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure>

<ul>
<li>这种方式可以解决构造函数形参名发生变化带来的耦合问题</li>
<li>但是如果构造方法参数中有类型相同的参数，这种方式就不太好实现了</li>
</ul>
<p>方式二:删除type属性，添加index属性，按照索引下标注入，下标从0开始</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;bookDao&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.dao.impl.BookDaoImpl&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">constructor-arg</span> <span class="attr">index</span>=<span class="string">&quot;1&quot;</span> <span class="attr">value</span>=<span class="string">&quot;100&quot;</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">constructor-arg</span> <span class="attr">index</span>=<span class="string">&quot;0&quot;</span> <span class="attr">value</span>=<span class="string">&quot;mysql&quot;</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure>

<ul>
<li>这种方式可以解决参数类型重复问题</li>
<li>但是如果构造方法参数顺序发生变化后，这种方式又带来了耦合问题</li>
</ul>
<p>介绍完两种参数的注入方式，具体我们该如何选择呢?</p>
<ol>
<li>强制依赖使用构造器进行，使用setter注入有概率不进行注入导致null对象出现<ul>
<li>强制依赖指对象在创建的过程中必须要注入指定的参数</li>
</ul>
</li>
<li>可选依赖使用setter注入进行，灵活性强<ul>
<li>可选依赖指对象在创建过程中注入的参数可有可无</li>
</ul>
</li>
<li>Spring框架倡导使用构造器，第三方框架内部大多数采用构造器注入的形式进行数据初始化，相对严谨</li>
<li>如果有必要可以两者同时使用，使用构造器注入完成强制依赖的注入，使用setter注入完成可选依赖的注入</li>
<li>实际开发过程中还要根据实际情况分析，如果受控对象没有提供setter方法就必须使用构造器注入</li>
<li><strong>&#x3D;&#x3D;自己开发的模块推荐使用setter注入&#x3D;&#x3D;</strong></li>
</ol>
<p>这节中主要讲解的是Spring的依赖注入的实现方式:</p>
<ul>
<li><p>setter注入</p>
<ul>
<li><p>简单数据类型</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">...</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;&quot;</span> <span class="attr">value</span>=<span class="string">&quot;&quot;</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>引用数据类型</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">...</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;&quot;</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure></li>
</ul>
</li>
<li><p>构造器注入</p>
<ul>
<li><p>简单数据类型</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">...</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">constructor-arg</span> <span class="attr">name</span>=<span class="string">&quot;&quot;</span> <span class="attr">index</span>=<span class="string">&quot;&quot;</span> <span class="attr">type</span>=<span class="string">&quot;&quot;</span> <span class="attr">value</span>=<span class="string">&quot;&quot;</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>引用数据类型</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">...</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">constructor-arg</span> <span class="attr">name</span>=<span class="string">&quot;&quot;</span> <span class="attr">index</span>=<span class="string">&quot;&quot;</span> <span class="attr">type</span>=<span class="string">&quot;&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;&quot;</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure></li>
</ul>
</li>
<li><p>依赖注入的方式选择上</p>
<ul>
<li>建议使用setter注入</li>
<li>第三方技术根据情况选择</li>
</ul>
</li>
</ul>
<h3 id="5-3-自动配置"><a href="#5-3-自动配置" class="headerlink" title="5.3 自动配置"></a>5.3 自动配置</h3><p>前面花了大量的时间把Spring的注入去学习了下，总结起来就一个字&#x3D;&#x3D;麻烦&#x3D;&#x3D;。</p>
<p>问:麻烦在哪?</p>
<p>答:配置文件的编写配置上。</p>
<p>问:有更简单方式么?</p>
<p>答:有，自动配置</p>
<p>什么是自动配置以及如何实现自动配置，就是接下来要学习的内容：</p>
<h4 id="5-3-1-什么是依赖自动装配"><a href="#5-3-1-什么是依赖自动装配" class="headerlink" title="5.3.1 什么是依赖自动装配?"></a>5.3.1 什么是依赖自动装配?</h4><ul>
<li>IoC容器根据bean所依赖的资源在容器中自动查找并注入到bean中的过程称为自动装配</li>
</ul>
<h4 id="5-3-2-自动装配方式有哪些"><a href="#5-3-2-自动装配方式有哪些" class="headerlink" title="5.3.2 自动装配方式有哪些?"></a>5.3.2 自动装配方式有哪些?</h4><ul>
<li>&#x3D;&#x3D;按类型（常用）&#x3D;&#x3D;</li>
<li>按名称</li>
<li>按构造方法</li>
<li>不启用自动装配</li>
</ul>
<h4 id="5-3-3-准备下案例环境"><a href="#5-3-3-准备下案例环境" class="headerlink" title="5.3.3 准备下案例环境"></a>5.3.3 准备下案例环境</h4><ul>
<li>创建一个Maven项目</li>
<li>pom.xml添加依赖</li>
<li>resources下添加spring的配置文件</li>
</ul>
<p>这些步骤和前面的都一致，大家可以快速的拷贝即可，最终项目的结构如下:</p>
<p><img src="/images/1629805387647.png"></p>
<p>(1)项目中添加BookDao、BookDaoImpl、BookService和BookServiceImpl类</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">BookDao</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">BookDaoImpl</span> <span class="keyword">implements</span> <span class="title class_">BookDao</span> &#123;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">private</span> String databaseName;</span><br><span class="line">    <span class="keyword">private</span> <span class="type">int</span> connectionNum;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;book dao save ...&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">BookService</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">BookServiceImpl</span> <span class="keyword">implements</span> <span class="title class_">BookService</span>&#123;</span><br><span class="line">    <span class="keyword">private</span> BookDao bookDao;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setBookDao</span><span class="params">(BookDao bookDao)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.bookDao = bookDao;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;book service save ...&quot;</span>);</span><br><span class="line">        bookDao.save();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>(2)resources下提供spring的配置文件</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version=<span class="string">&quot;1.0&quot;</span> encoding=<span class="string">&quot;UTF-8&quot;</span>?&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">beans</span> <span class="attr">xmlns</span>=<span class="string">&quot;http://www.springframework.org/schema/beans&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:xsi</span>=<span class="string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xsi:schemaLocation</span>=<span class="string">&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd&quot;</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;bookDao&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.dao.impl.BookDaoImpl&quot;</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;bookService&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.service.impl.BookServiceImpl&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;bookDao&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;bookDao&quot;</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">beans</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p>(3)编写AppForAutoware运行类，加载Spring的IOC容器，并从中获取对应的bean对象</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">AppForAutoware</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">( String[] args )</span> &#123;</span><br><span class="line">        <span class="type">ApplicationContext</span> <span class="variable">ctx</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ClassPathXmlApplicationContext</span>(<span class="string">&quot;applicationContext.xml&quot;</span>);</span><br><span class="line">        <span class="type">BookService</span> <span class="variable">bookService</span> <span class="operator">=</span> (BookService) ctx.getBean(<span class="string">&quot;bookService&quot;</span>);</span><br><span class="line">        bookService.save();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h4 id="5-3-4-完成自动装配的配置"><a href="#5-3-4-完成自动装配的配置" class="headerlink" title="5.3.4 完成自动装配的配置"></a>5.3.4 完成自动装配的配置</h4><p>接下来，在上面这个环境中来完成<code>自动装配</code>的学习:</p>
<p>自动装配只需要修改applicationContext.xml配置文件即可:</p>
<p>(1)将<code>&lt;property&gt;</code>标签删除</p>
<p>(2)在<code>&lt;bean&gt;</code>标签中添加autowire属性</p>
<p>首先来实现按照类型注入的配置</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version=<span class="string">&quot;1.0&quot;</span> encoding=<span class="string">&quot;UTF-8&quot;</span>?&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">beans</span> <span class="attr">xmlns</span>=<span class="string">&quot;http://www.springframework.org/schema/beans&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:xsi</span>=<span class="string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xsi:schemaLocation</span>=<span class="string">&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd&quot;</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.dao.impl.BookDaoImpl&quot;</span>/&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--autowire属性：开启自动装配，通常使用按类型装配--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;bookService&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.service.impl.BookServiceImpl&quot;</span> <span class="attr">autowire</span>=<span class="string">&quot;byType&quot;</span>/&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;/<span class="name">beans</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p>&#x3D;&#x3D;注意事项:&#x3D;&#x3D;</p>
<ul>
<li>需要注入属性的类中对应属性的setter方法不能省略</li>
<li>被注入的对象必须要被Spring的IOC容器管理</li>
<li>按照类型在Spring的IOC容器中如果找到多个对象，会报<code>NoUniqueBeanDefinitionException</code></li>
</ul>
<p>一个类型在IOC中有多个对象，还想要注入成功，这个时候就需要按照名称注入，配置方式为:</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version=<span class="string">&quot;1.0&quot;</span> encoding=<span class="string">&quot;UTF-8&quot;</span>?&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">beans</span> <span class="attr">xmlns</span>=<span class="string">&quot;http://www.springframework.org/schema/beans&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:xsi</span>=<span class="string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xsi:schemaLocation</span>=<span class="string">&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd&quot;</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.dao.impl.BookDaoImpl&quot;</span>/&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--autowire属性：开启自动装配，通常使用按类型装配--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;bookService&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.service.impl.BookServiceImpl&quot;</span> <span class="attr">autowire</span>=<span class="string">&quot;byName&quot;</span>/&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;/<span class="name">beans</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p>&#x3D;&#x3D;注意事项:&#x3D;&#x3D;</p>
<ul>
<li><p>按照名称注入中的名称指的是什么?</p>
<p><img src="/images/1629806856156.png"></p>
<ul>
<li>bookDao是private修饰的，外部类无法直接方法</li>
<li>外部类只能通过属性的set方法进行访问</li>
<li>对外部类来说，setBookDao方法名，去掉set后首字母小写是其属性名<ul>
<li>为什么是去掉set首字母小写?</li>
<li>这个规则是set方法生成的默认规则，set方法的生成是把属性名首字母大写前面加set形成的方法名</li>
</ul>
</li>
<li>所以按照名称注入，其实是和对应的set方法有关，但是如果按照标准起名称，属性名和set对应的名是一致的</li>
</ul>
</li>
<li><p>如果按照名称去找对应的bean对象，找不到则注入Null</p>
</li>
<li><p>当某一个类型在IOC容器中有多个对象，按照名称注入只找其指定名称对应的bean对象，不会报错</p>
</li>
</ul>
<p>两种方式介绍完后，以后用的更多的是&#x3D;&#x3D;按照类型&#x3D;&#x3D;注入。</p>
<p>最后对于依赖注入，需要注意一些其他的配置特征:</p>
<ol>
<li>自动装配用于引用类型依赖注入，不能对简单类型进行操作</li>
<li>使用按类型装配时（byType）必须保障容器中相同类型的bean唯一，推荐使用</li>
<li>使用按名称装配时（byName）必须保障容器中具有指定名称的bean，因变量名与配置耦合，不推荐使用</li>
<li>自动装配优先级低于setter注入与构造器注入，同时出现时自动装配配置失效</li>
</ol>
<h3 id="5-4-集合注入"><a href="#5-4-集合注入" class="headerlink" title="5.4 集合注入"></a>5.4 集合注入</h3><p>前面我们已经能完成引入数据类型和简单数据类型的注入，但是还有一种数据类型&#x3D;&#x3D;集合&#x3D;&#x3D;，集合中既可以装简单数据类型也可以装引用数据类型，对于集合，在Spring中该如何注入呢?</p>
<p>先来回顾下，常见的集合类型有哪些?</p>
<ul>
<li>数组</li>
<li>List</li>
<li>Set</li>
<li>Map</li>
<li>Properties</li>
</ul>
<p>针对不同的集合类型，该如何实现注入呢?</p>
<h4 id="5-4-1-环境准备"><a href="#5-4-1-环境准备" class="headerlink" title="5.4.1 环境准备"></a>5.4.1 环境准备</h4><ul>
<li>创建一个Maven项目</li>
<li>pom.xml添加依赖</li>
<li>resources下添加spring的配置文件applicationContext.xml</li>
</ul>
<p>这些步骤和前面的都一致，大家可以快速的拷贝即可，最终项目的结构如下:</p>
<p><img src="/images/1629807579330.png"></p>
<p>(1)项目中添加添加BookDao、BookDaoImpl类</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">BookDao</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">BookDaoImpl</span> <span class="keyword">implements</span> <span class="title class_">BookDao</span> &#123;</span><br><span class="line">    </span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">BookDaoImpl</span> <span class="keyword">implements</span> <span class="title class_">BookDao</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="type">int</span>[] array;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> List&lt;String&gt; list;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> Set&lt;String&gt; set;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> Map&lt;String,String&gt; map;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> Properties properties;</span><br><span class="line"></span><br><span class="line">     <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">save</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;book dao save ...&quot;</span>);</span><br><span class="line"></span><br><span class="line">        System.out.println(<span class="string">&quot;遍历数组:&quot;</span> + Arrays.toString(array));</span><br><span class="line"></span><br><span class="line">        System.out.println(<span class="string">&quot;遍历List&quot;</span> + list);</span><br><span class="line"></span><br><span class="line">        System.out.println(<span class="string">&quot;遍历Set&quot;</span> + set);</span><br><span class="line"></span><br><span class="line">        System.out.println(<span class="string">&quot;遍历Map&quot;</span> + map);</span><br><span class="line"></span><br><span class="line">        System.out.println(<span class="string">&quot;遍历Properties&quot;</span> + properties);</span><br><span class="line">    &#125;</span><br><span class="line">	<span class="comment">//setter....方法省略，自己使用工具生成</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>(2)resources下提供spring的配置文件，applicationContext.xml</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version=<span class="string">&quot;1.0&quot;</span> encoding=<span class="string">&quot;UTF-8&quot;</span>?&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">beans</span> <span class="attr">xmlns</span>=<span class="string">&quot;http://www.springframework.org/schema/beans&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:xsi</span>=<span class="string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xsi:schemaLocation</span>=<span class="string">&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd&quot;</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;bookDao&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.dao.impl.BookDaoImpl&quot;</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">beans</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p>(3)编写AppForDICollection运行类，加载Spring的IOC容器，并从中获取对应的bean对象</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">AppForDICollection</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">( String[] args )</span> &#123;</span><br><span class="line">        <span class="type">ApplicationContext</span> <span class="variable">ctx</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ClassPathXmlApplicationContext</span>(<span class="string">&quot;applicationContext.xml&quot;</span>);</span><br><span class="line">        <span class="type">BookDao</span> <span class="variable">bookDao</span> <span class="operator">=</span> (BookDao) ctx.getBean(<span class="string">&quot;bookDao&quot;</span>);</span><br><span class="line">        bookDao.save();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>接下来，在上面这个环境中来完成<code>集合注入</code>的学习:</p>
<p>下面的所以配置方式，都是在bookDao的bean标签中使用<property>进行注入</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version=<span class="string">&quot;1.0&quot;</span> encoding=<span class="string">&quot;UTF-8&quot;</span>?&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">beans</span> <span class="attr">xmlns</span>=<span class="string">&quot;http://www.springframework.org/schema/beans&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:xsi</span>=<span class="string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xsi:schemaLocation</span>=<span class="string">&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd&quot;</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;bookDao&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.dao.impl.BookDaoImpl&quot;</span>&gt;</span></span><br><span class="line">        </span><br><span class="line">    <span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">beans</span>&gt;</span></span><br></pre></td></tr></table></figure>

<h4 id="5-4-2-注入数组类型数据"><a href="#5-4-2-注入数组类型数据" class="headerlink" title="5.4.2 注入数组类型数据"></a>5.4.2 注入数组类型数据</h4><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;array&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">array</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">value</span>&gt;</span>100<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">value</span>&gt;</span>200<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">value</span>&gt;</span>300<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">array</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br></pre></td></tr></table></figure>

<h4 id="5-4-3-注入List类型数据"><a href="#5-4-3-注入List类型数据" class="headerlink" title="5.4.3 注入List类型数据"></a>5.4.3 注入List类型数据</h4><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;list&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">list</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">value</span>&gt;</span>itcast<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">value</span>&gt;</span>itheima<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">value</span>&gt;</span>boxuegu<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">value</span>&gt;</span>chuanzhihui<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">list</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br></pre></td></tr></table></figure>

<h4 id="5-4-4-注入Set类型数据"><a href="#5-4-4-注入Set类型数据" class="headerlink" title="5.4.4 注入Set类型数据"></a>5.4.4 注入Set类型数据</h4><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;set&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">set</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">value</span>&gt;</span>itcast<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">value</span>&gt;</span>itheima<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">value</span>&gt;</span>boxuegu<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">value</span>&gt;</span>boxuegu<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">set</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br></pre></td></tr></table></figure>

<h4 id="5-4-5-注入Map类型数据"><a href="#5-4-5-注入Map类型数据" class="headerlink" title="5.4.5 注入Map类型数据"></a>5.4.5 注入Map类型数据</h4><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;map&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">map</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">entry</span> <span class="attr">key</span>=<span class="string">&quot;country&quot;</span> <span class="attr">value</span>=<span class="string">&quot;china&quot;</span>/&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">entry</span> <span class="attr">key</span>=<span class="string">&quot;province&quot;</span> <span class="attr">value</span>=<span class="string">&quot;henan&quot;</span>/&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">entry</span> <span class="attr">key</span>=<span class="string">&quot;city&quot;</span> <span class="attr">value</span>=<span class="string">&quot;kaifeng&quot;</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">map</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br></pre></td></tr></table></figure>

<h4 id="5-4-6-注入Properties类型数据"><a href="#5-4-6-注入Properties类型数据" class="headerlink" title="5.4.6 注入Properties类型数据"></a>5.4.6 注入Properties类型数据</h4><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;properties&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">props</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">prop</span> <span class="attr">key</span>=<span class="string">&quot;country&quot;</span>&gt;</span>china<span class="tag">&lt;/<span class="name">prop</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">prop</span> <span class="attr">key</span>=<span class="string">&quot;province&quot;</span>&gt;</span>henan<span class="tag">&lt;/<span class="name">prop</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">prop</span> <span class="attr">key</span>=<span class="string">&quot;city&quot;</span>&gt;</span>kaifeng<span class="tag">&lt;/<span class="name">prop</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">props</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p>配置完成后，运行下看结果:</p>
<p><img src="/images/1629808046783.png"></p>
<p><strong>说明：</strong></p>
<ul>
<li>property标签表示setter方式注入，构造方式注入constructor-arg标签内部也可以写<code>&lt;array&gt;</code>、<code>&lt;list&gt;</code>、<code>&lt;set&gt;</code>、<code>&lt;map&gt;</code>、<code>&lt;props&gt;</code>标签</li>
<li>List的底层也是通过数组实现的，所以<code>&lt;list&gt;</code>和<code>&lt;array&gt;</code>标签是可以混用</li>
<li>集合中要添加引用类型，只需要把<code>&lt;value&gt;</code>标签改成<code>&lt;ref&gt;</code>标签，这种方式用的比较少</li>
</ul>

    </div>

    
    
    
        

<div>
<ul class="post-copyright">
  <li class="post-copyright-author">
    <strong>本文作者： </strong>Daorong Xing
  </li>
  <li class="post-copyright-link">
    <strong>本文链接：</strong>
    <a href="https://daorongxing.gitee.io/post/3701/" title="Spring_1">https://daorongxing.gitee.io/post/3701/</a>
  </li>
  <li class="post-copyright-license">
    <strong>版权声明： </strong>本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" rel="noopener" target="_blank"><i class="fab fa-fw fa-creative-commons"></i>BY-NC-SA</a> 许可协议。转载请注明出处！
  </li>
</ul>
</div>


      <footer class="post-footer">
          
          <div class="post-tags">
              <a href="/tags/Spring/" rel="tag"><i class="fa fa-tag"></i> Spring</a>
          </div>

        


        
    <div class="post-nav">
      <div class="post-nav-item">
    <a href="/post/370/" rel="prev" title="GC">
      <i class="fa fa-chevron-left"></i> GC
    </a></div>
      <div class="post-nav-item">
    <a href="/post/24714/" rel="next" title="类结构和类加载">
      类结构和类加载 <i class="fa fa-chevron-right"></i>
    </a></div>
    </div>
      </footer>
    
  </article>
  
  
  



          </div>
          

<script>
  window.addEventListener('tabs:register', () => {
    let { activeClass } = CONFIG.comments;
    if (CONFIG.comments.storage) {
      activeClass = localStorage.getItem('comments_active') || activeClass;
    }
    if (activeClass) {
      let activeTab = document.querySelector(`a[href="#comment-${activeClass}"]`);
      if (activeTab) {
        activeTab.click();
      }
    }
  });
  if (CONFIG.comments.storage) {
    window.addEventListener('tabs:click', event => {
      if (!event.target.matches('.tabs-comment .tab-content .tab-pane')) return;
      let commentClass = event.target.classList[1];
      localStorage.setItem('comments_active', commentClass);
    });
  }
</script>

        </div>
          
  
  <div class="toggle sidebar-toggle">
    <span class="toggle-line toggle-line-first"></span>
    <span class="toggle-line toggle-line-middle"></span>
    <span class="toggle-line toggle-line-last"></span>
  </div>

  <aside class="sidebar">
    <div class="sidebar-inner">

      <ul class="sidebar-nav motion-element">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <!--noindex-->
      <div class="post-toc-wrap sidebar-panel">
          <div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#Spring-day01"><span class="nav-text">Spring_day01</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#1%EF%BC%8C%E8%AF%BE%E7%A8%8B%E4%BB%8B%E7%BB%8D"><span class="nav-text">1，课程介绍</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#1-1-%E4%B8%BA%E4%BB%80%E4%B9%88%E8%A6%81%E5%AD%A6"><span class="nav-text">1.1 为什么要学?</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#1-2-%E5%AD%A6%E4%BB%80%E4%B9%88"><span class="nav-text">1.2 学什么?</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#1-3-%E6%80%8E%E4%B9%88%E5%AD%A6"><span class="nav-text">1.3 怎么学?</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#2%EF%BC%8CSpring%E7%9B%B8%E5%85%B3%E6%A6%82%E5%BF%B5"><span class="nav-text">2，Spring相关概念</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#2-1-%E5%88%9D%E8%AF%86Spring"><span class="nav-text">2.1 初识Spring</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#2-1-1-Spring%E5%AE%B6%E6%97%8F"><span class="nav-text">2.1.1 Spring家族</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#2-1-2-%E4%BA%86%E8%A7%A3Spring%E5%8F%91%E5%B1%95%E5%8F%B2"><span class="nav-text">2.1.2 了解Spring发展史</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#2-2-Spring%E7%B3%BB%E7%BB%9F%E6%9E%B6%E6%9E%84"><span class="nav-text">2.2 Spring系统架构</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#2-2-1-%E7%B3%BB%E7%BB%9F%E6%9E%B6%E6%9E%84%E5%9B%BE"><span class="nav-text">2.2.1 系统架构图</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#2-2-2-%E8%AF%BE%E7%A8%8B%E5%AD%A6%E4%B9%A0%E8%B7%AF%E7%BA%BF"><span class="nav-text">2.2.2 课程学习路线</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#2-3-Spring%E6%A0%B8%E5%BF%83%E6%A6%82%E5%BF%B5"><span class="nav-text">2.3 Spring核心概念</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#2-3-1-%E7%9B%AE%E5%89%8D%E9%A1%B9%E7%9B%AE%E4%B8%AD%E7%9A%84%E9%97%AE%E9%A2%98"><span class="nav-text">2.3.1 目前项目中的问题</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#2-3-2-IOC%E3%80%81IOC%E5%AE%B9%E5%99%A8%E3%80%81Bean%E3%80%81DI"><span class="nav-text">2.3.2 IOC、IOC容器、Bean、DI</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#2-3-3-%E6%A0%B8%E5%BF%83%E6%A6%82%E5%BF%B5%E5%B0%8F%E7%BB%93"><span class="nav-text">2.3.3 核心概念小结</span></a></li></ol></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#3%EF%BC%8C%E5%85%A5%E9%97%A8%E6%A1%88%E4%BE%8B"><span class="nav-text">3，入门案例</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#3-1-IOC%E5%85%A5%E9%97%A8%E6%A1%88%E4%BE%8B"><span class="nav-text">3.1 IOC入门案例</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#3-1-1-%E5%85%A5%E9%97%A8%E6%A1%88%E4%BE%8B%E6%80%9D%E8%B7%AF%E5%88%86%E6%9E%90"><span class="nav-text">3.1.1 入门案例思路分析</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#3-1-2-%E5%85%A5%E9%97%A8%E6%A1%88%E4%BE%8B%E4%BB%A3%E7%A0%81%E5%AE%9E%E7%8E%B0"><span class="nav-text">3.1.2 入门案例代码实现</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#%E6%AD%A5%E9%AA%A41-%E5%88%9B%E5%BB%BAMaven%E9%A1%B9%E7%9B%AE"><span class="nav-text">步骤1:创建Maven项目</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#%E6%AD%A5%E9%AA%A42-%E6%B7%BB%E5%8A%A0Spring%E7%9A%84%E4%BE%9D%E8%B5%96jar%E5%8C%85"><span class="nav-text">步骤2:添加Spring的依赖jar包</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#%E6%AD%A5%E9%AA%A43-%E6%B7%BB%E5%8A%A0%E6%A1%88%E4%BE%8B%E4%B8%AD%E9%9C%80%E8%A6%81%E7%9A%84%E7%B1%BB"><span class="nav-text">步骤3:添加案例中需要的类</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#%E6%AD%A5%E9%AA%A44-%E6%B7%BB%E5%8A%A0spring%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6"><span class="nav-text">步骤4:添加spring配置文件</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#%E6%AD%A5%E9%AA%A45-%E5%9C%A8%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E4%B8%AD%E5%AE%8C%E6%88%90bean%E7%9A%84%E9%85%8D%E7%BD%AE"><span class="nav-text">步骤5:在配置文件中完成bean的配置</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#%E6%AD%A5%E9%AA%A46-%E8%8E%B7%E5%8F%96IOC%E5%AE%B9%E5%99%A8"><span class="nav-text">步骤6:获取IOC容器</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#%E6%AD%A5%E9%AA%A47-%E4%BB%8E%E5%AE%B9%E5%99%A8%E4%B8%AD%E8%8E%B7%E5%8F%96%E5%AF%B9%E8%B1%A1%E8%BF%9B%E8%A1%8C%E6%96%B9%E6%B3%95%E8%B0%83%E7%94%A8"><span class="nav-text">步骤7:从容器中获取对象进行方法调用</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#%E6%AD%A5%E9%AA%A48-%E8%BF%90%E8%A1%8C%E7%A8%8B%E5%BA%8F"><span class="nav-text">步骤8:运行程序</span></a></li></ol></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#3-2-DI%E5%85%A5%E9%97%A8%E6%A1%88%E4%BE%8B"><span class="nav-text">3.2 DI入门案例</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#3-2-1-%E5%85%A5%E9%97%A8%E6%A1%88%E4%BE%8B%E6%80%9D%E8%B7%AF%E5%88%86%E6%9E%90"><span class="nav-text">3.2.1 入门案例思路分析</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#3-2-2-%E5%85%A5%E9%97%A8%E6%A1%88%E4%BE%8B%E4%BB%A3%E7%A0%81%E5%AE%9E%E7%8E%B0"><span class="nav-text">3.2.2 入门案例代码实现</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#%E6%AD%A5%E9%AA%A41-%E5%8E%BB%E9%99%A4%E4%BB%A3%E7%A0%81%E4%B8%AD%E7%9A%84new"><span class="nav-text">步骤1: 去除代码中的new</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#%E6%AD%A5%E9%AA%A42-%E4%B8%BA%E5%B1%9E%E6%80%A7%E6%8F%90%E4%BE%9Bsetter%E6%96%B9%E6%B3%95"><span class="nav-text">步骤2:为属性提供setter方法</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#%E6%AD%A5%E9%AA%A43-%E4%BF%AE%E6%94%B9%E9%85%8D%E7%BD%AE%E5%AE%8C%E6%88%90%E6%B3%A8%E5%85%A5"><span class="nav-text">步骤3:修改配置完成注入</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#%E6%AD%A5%E9%AA%A44-%E8%BF%90%E8%A1%8C%E7%A8%8B%E5%BA%8F"><span class="nav-text">步骤4:运行程序</span></a></li></ol></li></ol></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#4%EF%BC%8CIOC%E7%9B%B8%E5%85%B3%E5%86%85%E5%AE%B9"><span class="nav-text">4，IOC相关内容</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#4-1-bean%E5%9F%BA%E7%A1%80%E9%85%8D%E7%BD%AE"><span class="nav-text">4.1 bean基础配置</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#4-1-1-bean%E5%9F%BA%E7%A1%80%E9%85%8D%E7%BD%AE-id%E4%B8%8Eclass"><span class="nav-text">4.1.1 bean基础配置(id与class)</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#4-1-2-bean%E7%9A%84name%E5%B1%9E%E6%80%A7"><span class="nav-text">4.1.2 bean的name属性</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#%E6%AD%A5%E9%AA%A41%EF%BC%9A%E9%85%8D%E7%BD%AE%E5%88%AB%E5%90%8D"><span class="nav-text">步骤1：配置别名</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#%E6%AD%A5%E9%AA%A42-%E6%A0%B9%E6%8D%AE%E5%90%8D%E7%A7%B0%E5%AE%B9%E5%99%A8%E4%B8%AD%E8%8E%B7%E5%8F%96bean%E5%AF%B9%E8%B1%A1"><span class="nav-text">步骤2:根据名称容器中获取bean对象</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#%E6%AD%A5%E9%AA%A43-%E8%BF%90%E8%A1%8C%E7%A8%8B%E5%BA%8F"><span class="nav-text">步骤3:运行程序</span></a></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#4-1-3-bean%E4%BD%9C%E7%94%A8%E8%8C%83%E5%9B%B4scope%E9%85%8D%E7%BD%AE"><span class="nav-text">4.1.3 bean作用范围scope配置</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#4-1-3-1-%E9%AA%8C%E8%AF%81IOC%E5%AE%B9%E5%99%A8%E4%B8%AD%E5%AF%B9%E8%B1%A1%E6%98%AF%E5%90%A6%E4%B8%BA%E5%8D%95%E4%BE%8B"><span class="nav-text">4.1.3.1 验证IOC容器中对象是否为单例</span></a><ol class="nav-child"><li class="nav-item nav-level-6"><a class="nav-link" href="#%E9%AA%8C%E8%AF%81%E6%80%9D%E8%B7%AF"><span class="nav-text">验证思路</span></a></li><li class="nav-item nav-level-6"><a class="nav-link" href="#%E5%85%B7%E4%BD%93%E5%AE%9E%E7%8E%B0"><span class="nav-text">具体实现</span></a></li></ol></li><li class="nav-item nav-level-5"><a class="nav-link" href="#4-1-3-2-%E9%85%8D%E7%BD%AEbean%E4%B8%BA%E9%9D%9E%E5%8D%95%E4%BE%8B"><span class="nav-text">4.1.3.2 配置bean为非单例</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#4-1-3-3-scope%E4%BD%BF%E7%94%A8%E5%90%8E%E7%BB%AD%E6%80%9D%E8%80%83"><span class="nav-text">4.1.3.3 scope使用后续思考</span></a></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#4-14-bean%E5%9F%BA%E7%A1%80%E9%85%8D%E7%BD%AE%E5%B0%8F%E7%BB%93"><span class="nav-text">4.14 bean基础配置小结</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#4-2-bean%E5%AE%9E%E4%BE%8B%E5%8C%96"><span class="nav-text">4.2 bean实例化</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#4-2-1-%E7%8E%AF%E5%A2%83%E5%87%86%E5%A4%87"><span class="nav-text">4.2.1 环境准备</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#4-2-2-%E6%9E%84%E9%80%A0%E6%96%B9%E6%B3%95%E5%AE%9E%E4%BE%8B%E5%8C%96"><span class="nav-text">4.2.2 构造方法实例化</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#%E6%AD%A5%E9%AA%A41-%E5%87%86%E5%A4%87%E9%9C%80%E8%A6%81%E8%A2%AB%E5%88%9B%E5%BB%BA%E7%9A%84%E7%B1%BB"><span class="nav-text">步骤1:准备需要被创建的类</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#%E6%AD%A5%E9%AA%A42-%E5%B0%86%E7%B1%BB%E9%85%8D%E7%BD%AE%E5%88%B0Spring%E5%AE%B9%E5%99%A8"><span class="nav-text">步骤2:将类配置到Spring容器</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#%E6%AD%A5%E9%AA%A43-%E7%BC%96%E5%86%99%E8%BF%90%E8%A1%8C%E7%A8%8B%E5%BA%8F"><span class="nav-text">步骤3:编写运行程序</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#%E6%AD%A5%E9%AA%A44-%E7%B1%BB%E4%B8%AD%E6%8F%90%E4%BE%9B%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0%E6%B5%8B%E8%AF%95"><span class="nav-text">步骤4:类中提供构造函数测试</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#%E6%AD%A5%E9%AA%A45-%E5%B0%86%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0%E6%94%B9%E6%88%90private%E6%B5%8B%E8%AF%95"><span class="nav-text">步骤5:将构造函数改成private测试</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#%E6%AD%A5%E9%AA%A46-%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0%E4%B8%AD%E6%B7%BB%E5%8A%A0%E4%B8%80%E4%B8%AA%E5%8F%82%E6%95%B0%E6%B5%8B%E8%AF%95"><span class="nav-text">步骤6:构造函数中添加一个参数测试</span></a></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#4-2-3-%E5%88%86%E6%9E%90Spring%E7%9A%84%E9%94%99%E8%AF%AF%E4%BF%A1%E6%81%AF-%E7%AE%80%E5%8D%95%E7%9C%8B%E7%9C%8B%E5%B0%B1%E5%A5%BD%E4%BA%86"><span class="nav-text">4.2.3 分析Spring的错误信息(简单看看就好了)</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#4-2-4-%E9%9D%99%E6%80%81%E5%B7%A5%E5%8E%82%E5%AE%9E%E4%BE%8B%E5%8C%96"><span class="nav-text">4.2.4 静态工厂实例化</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#4-2-4-1-%E5%B7%A5%E5%8E%82%E6%96%B9%E5%BC%8F%E5%88%9B%E5%BB%BAbean"><span class="nav-text">4.2.4.1 工厂方式创建bean</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#4-2-4-2-%E9%9D%99%E6%80%81%E5%B7%A5%E5%8E%82%E5%AE%9E%E4%BE%8B%E5%8C%96"><span class="nav-text">4.2.4.2 静态工厂实例化</span></a></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#4-2-5-%E5%AE%9E%E4%BE%8B%E5%B7%A5%E5%8E%82%E4%B8%8EFactoryBean"><span class="nav-text">4.2.5 实例工厂与FactoryBean</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#4-2-3-1-%E7%8E%AF%E5%A2%83%E5%87%86%E5%A4%87"><span class="nav-text">4.2.3.1 环境准备</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#4-2-3-2-%E5%AE%9E%E4%BE%8B%E5%B7%A5%E5%8E%82%E5%AE%9E%E4%BE%8B%E5%8C%96"><span class="nav-text">4.2.3.2 实例工厂实例化</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#4-2-3-3-FactoryBean%E7%9A%84%E4%BD%BF%E7%94%A8"><span class="nav-text">4.2.3.3 FactoryBean的使用</span></a></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#4-2-6-bean%E5%AE%9E%E4%BE%8B%E5%8C%96%E5%B0%8F%E7%BB%93"><span class="nav-text">4.2.6 bean实例化小结</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#4-3-bean%E7%9A%84%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F"><span class="nav-text">4.3 bean的生命周期</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#4-3-1-%E7%8E%AF%E5%A2%83%E5%87%86%E5%A4%87"><span class="nav-text">4.3.1 环境准备</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#4-3-2-%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E8%AE%BE%E7%BD%AE"><span class="nav-text">4.3.2 生命周期设置</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#%E6%AD%A5%E9%AA%A41-%E6%B7%BB%E5%8A%A0%E5%88%9D%E5%A7%8B%E5%8C%96%E5%92%8C%E9%94%80%E6%AF%81%E6%96%B9%E6%B3%95"><span class="nav-text">步骤1:添加初始化和销毁方法</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#%E6%AD%A5%E9%AA%A42-%E9%85%8D%E7%BD%AE%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F"><span class="nav-text">步骤2:配置生命周期</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#%E6%AD%A5%E9%AA%A43-%E8%BF%90%E8%A1%8C%E7%A8%8B%E5%BA%8F-1"><span class="nav-text">步骤3:运行程序</span></a></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#4-3-3-close%E5%85%B3%E9%97%AD%E5%AE%B9%E5%99%A8"><span class="nav-text">4.3.3 close关闭容器</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#4-3-4-%E6%B3%A8%E5%86%8C%E9%92%A9%E5%AD%90%E5%85%B3%E9%97%AD%E5%AE%B9%E5%99%A8"><span class="nav-text">4.3.4 注册钩子关闭容器</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#4-3-5-bean%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E5%B0%8F%E7%BB%93"><span class="nav-text">4.3.5 bean生命周期小结</span></a></li></ol></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#5%EF%BC%8CDI%E7%9B%B8%E5%85%B3%E5%86%85%E5%AE%B9"><span class="nav-text">5，DI相关内容</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#5-1-setter%E6%B3%A8%E5%85%A5"><span class="nav-text">5.1 setter注入</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#5-1-1-%E7%8E%AF%E5%A2%83%E5%87%86%E5%A4%87"><span class="nav-text">5.1.1 环境准备</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#5-1-2-%E6%B3%A8%E5%85%A5%E5%BC%95%E7%94%A8%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B"><span class="nav-text">5.1.2 注入引用数据类型</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#%E6%AD%A5%E9%AA%A41-%E5%A3%B0%E6%98%8E%E5%B1%9E%E6%80%A7%E5%B9%B6%E6%8F%90%E4%BE%9Bsetter%E6%96%B9%E6%B3%95"><span class="nav-text">步骤1:声明属性并提供setter方法</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#%E6%AD%A5%E9%AA%A42-%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E4%B8%AD%E8%BF%9B%E8%A1%8C%E6%B3%A8%E5%85%A5%E9%85%8D%E7%BD%AE"><span class="nav-text">步骤2:配置文件中进行注入配置</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#%E6%AD%A5%E9%AA%A43-%E8%BF%90%E8%A1%8C%E7%A8%8B%E5%BA%8F-2"><span class="nav-text">步骤3:运行程序</span></a></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#5-1-3-%E6%B3%A8%E5%85%A5%E7%AE%80%E5%8D%95%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B"><span class="nav-text">5.1.3 注入简单数据类型</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#%E6%AD%A5%E9%AA%A41-%E5%A3%B0%E6%98%8E%E5%B1%9E%E6%80%A7%E5%B9%B6%E6%8F%90%E4%BE%9Bsetter%E6%96%B9%E6%B3%95-1"><span class="nav-text">步骤1:声明属性并提供setter方法</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#%E6%AD%A5%E9%AA%A42-%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E4%B8%AD%E8%BF%9B%E8%A1%8C%E6%B3%A8%E5%85%A5%E9%85%8D%E7%BD%AE-1"><span class="nav-text">步骤2:配置文件中进行注入配置</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#%E6%AD%A5%E9%AA%A43-%E8%BF%90%E8%A1%8C%E7%A8%8B%E5%BA%8F-3"><span class="nav-text">步骤3:运行程序</span></a></li></ol></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#5-2-%E6%9E%84%E9%80%A0%E5%99%A8%E6%B3%A8%E5%85%A5"><span class="nav-text">5.2 构造器注入</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#5-2-1-%E7%8E%AF%E5%A2%83%E5%87%86%E5%A4%87"><span class="nav-text">5.2.1 环境准备</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#5-2-2-%E6%9E%84%E9%80%A0%E5%99%A8%E6%B3%A8%E5%85%A5%E5%BC%95%E7%94%A8%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B"><span class="nav-text">5.2.2 构造器注入引用数据类型</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#%E6%AD%A5%E9%AA%A41-%E5%88%A0%E9%99%A4setter%E6%96%B9%E6%B3%95%E5%B9%B6%E6%8F%90%E4%BE%9B%E6%9E%84%E9%80%A0%E6%96%B9%E6%B3%95"><span class="nav-text">步骤1:删除setter方法并提供构造方法</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#%E6%AD%A5%E9%AA%A42-%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E4%B8%AD%E8%BF%9B%E8%A1%8C%E9%85%8D%E7%BD%AE%E6%9E%84%E9%80%A0%E6%96%B9%E5%BC%8F%E6%B3%A8%E5%85%A5"><span class="nav-text">步骤2:配置文件中进行配置构造方式注入</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#%E6%AD%A5%E9%AA%A43%EF%BC%9A%E8%BF%90%E8%A1%8C%E7%A8%8B%E5%BA%8F"><span class="nav-text">步骤3：运行程序</span></a></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#5-2-3-%E6%9E%84%E9%80%A0%E5%99%A8%E6%B3%A8%E5%85%A5%E5%A4%9A%E4%B8%AA%E5%BC%95%E7%94%A8%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B"><span class="nav-text">5.2.3 构造器注入多个引用数据类型</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#%E6%AD%A5%E9%AA%A41-%E6%8F%90%E4%BE%9B%E5%A4%9A%E4%B8%AA%E5%B1%9E%E6%80%A7%E7%9A%84%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0"><span class="nav-text">步骤1:提供多个属性的构造函数</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#%E6%AD%A5%E9%AA%A43-%E8%BF%90%E8%A1%8C%E7%A8%8B%E5%BA%8F-4"><span class="nav-text">步骤3:运行程序</span></a></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#5-2-4-%E6%9E%84%E9%80%A0%E5%99%A8%E6%B3%A8%E5%85%A5%E5%A4%9A%E4%B8%AA%E7%AE%80%E5%8D%95%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B"><span class="nav-text">5.2.4 构造器注入多个简单数据类型</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#%E6%AD%A5%E9%AA%A41-%E6%B7%BB%E5%8A%A0%E5%A4%9A%E4%B8%AA%E7%AE%80%E5%8D%95%E5%B1%9E%E6%80%A7%E5%B9%B6%E6%8F%90%E4%BE%9B%E6%9E%84%E9%80%A0%E6%96%B9%E6%B3%95"><span class="nav-text">步骤1:添加多个简单属性并提供构造方法</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#%E6%AD%A5%E9%AA%A42-%E9%85%8D%E7%BD%AE%E5%AE%8C%E6%88%90%E5%A4%9A%E4%B8%AA%E5%B1%9E%E6%80%A7%E6%9E%84%E9%80%A0%E5%99%A8%E6%B3%A8%E5%85%A5"><span class="nav-text">步骤2:配置完成多个属性构造器注入</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#%E6%AD%A5%E9%AA%A43-%E8%BF%90%E8%A1%8C%E7%A8%8B%E5%BA%8F-5"><span class="nav-text">步骤3:运行程序</span></a></li></ol></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#5-3-%E8%87%AA%E5%8A%A8%E9%85%8D%E7%BD%AE"><span class="nav-text">5.3 自动配置</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#5-3-1-%E4%BB%80%E4%B9%88%E6%98%AF%E4%BE%9D%E8%B5%96%E8%87%AA%E5%8A%A8%E8%A3%85%E9%85%8D"><span class="nav-text">5.3.1 什么是依赖自动装配?</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#5-3-2-%E8%87%AA%E5%8A%A8%E8%A3%85%E9%85%8D%E6%96%B9%E5%BC%8F%E6%9C%89%E5%93%AA%E4%BA%9B"><span class="nav-text">5.3.2 自动装配方式有哪些?</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#5-3-3-%E5%87%86%E5%A4%87%E4%B8%8B%E6%A1%88%E4%BE%8B%E7%8E%AF%E5%A2%83"><span class="nav-text">5.3.3 准备下案例环境</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#5-3-4-%E5%AE%8C%E6%88%90%E8%87%AA%E5%8A%A8%E8%A3%85%E9%85%8D%E7%9A%84%E9%85%8D%E7%BD%AE"><span class="nav-text">5.3.4 完成自动装配的配置</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#5-4-%E9%9B%86%E5%90%88%E6%B3%A8%E5%85%A5"><span class="nav-text">5.4 集合注入</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#5-4-1-%E7%8E%AF%E5%A2%83%E5%87%86%E5%A4%87"><span class="nav-text">5.4.1 环境准备</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#5-4-2-%E6%B3%A8%E5%85%A5%E6%95%B0%E7%BB%84%E7%B1%BB%E5%9E%8B%E6%95%B0%E6%8D%AE"><span class="nav-text">5.4.2 注入数组类型数据</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#5-4-3-%E6%B3%A8%E5%85%A5List%E7%B1%BB%E5%9E%8B%E6%95%B0%E6%8D%AE"><span class="nav-text">5.4.3 注入List类型数据</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#5-4-4-%E6%B3%A8%E5%85%A5Set%E7%B1%BB%E5%9E%8B%E6%95%B0%E6%8D%AE"><span class="nav-text">5.4.4 注入Set类型数据</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#5-4-5-%E6%B3%A8%E5%85%A5Map%E7%B1%BB%E5%9E%8B%E6%95%B0%E6%8D%AE"><span class="nav-text">5.4.5 注入Map类型数据</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#5-4-6-%E6%B3%A8%E5%85%A5Properties%E7%B1%BB%E5%9E%8B%E6%95%B0%E6%8D%AE"><span class="nav-text">5.4.6 注入Properties类型数据</span></a></li></ol></li></ol></li></ol></div>
      </div>
      <!--/noindex-->

      <div class="site-overview-wrap sidebar-panel">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
    <img class="site-author-image" itemprop="image" alt="Daorong Xing"
      src="/images/avatar.gif">
  <p class="site-author-name" itemprop="name">Daorong Xing</p>
  <div class="site-description" itemprop="description">这是我的个人博客，记录计算机学习之路！</div>
</div>
<div class="site-state-wrap motion-element">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
          <a href="/archives/">
        
          <span class="site-state-item-count">10</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
            <a href="/categories/">
          
        <span class="site-state-item-count">4</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
      <div class="site-state-item site-state-tags">
            <a href="/tags/">
          
        <span class="site-state-item-count">5</span>
        <span class="site-state-item-name">标签</span></a>
      </div>
  </nav>
</div>
  <div class="links-of-author motion-element">
      <span class="links-of-author-item">
        <a href="https://github.com/yourname" title="GitHub → https:&#x2F;&#x2F;github.com&#x2F;yourname" rel="noopener" target="_blank"><i class="fab fa-github fa-fw"></i></a>
      </span>
      <span class="links-of-author-item">
        <a href="/2630168952@qq.com" title="E-Mail → 2630168952@qq.com"><i class="fa fa-envelope fa-fw"></i></a>
      </span>
      <span class="links-of-author-item">
        <a href="/2630168952@qq.com" title="QQ → 2630168952@qq.com"><i class="fa fa-qq fa-fw"></i></a>
      </span>
  </div>



<script type="text/javascript" charset="utf-8" src="/js/tagcloud.js"></script>
<script type="text/javascript" charset="utf-8" src="/js/tagcanvas.js"></script>
<div class="widget-wrap">
    <h3 class="widget-title">标签云</h3>
    <div id="myCanvasContainer" class="widget tagcloud">
        <canvas width="250" height="250" id="resCanvas" style="width=100%">
            <ul class="tag-list" itemprop="keywords"><li class="tag-list-item"><a class="tag-list-link" href="/tags/JVM/" rel="tag">JVM</a><span class="tag-list-count">4</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Spring/" rel="tag">Spring</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E6%8C%87%E9%92%88/" rel="tag">指针</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E7%AE%97%E6%B3%95/" rel="tag">算法</a><span class="tag-list-count">3</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E7%BB%93%E6%9E%84%E4%BD%93/" rel="tag">结构体</a><span class="tag-list-count">1</span></li></ul>
        </canvas>
    </div>
</div>


      </div>
        <div class="back-to-top motion-element">
          <i class="fa fa-arrow-up"></i>
          <span>0%</span>
        </div>

    </div>
  </aside>
  <div id="sidebar-dimmer"></div>


      </div>
    </main>

    <footer class="footer">
      <div class="footer-inner">
        

        

<div class="copyright">
  
  &copy; 
  <span itemprop="copyrightYear">2022</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">Daorong Xing</span>
    <span class="post-meta-divider">|</span>
    <span class="post-meta-item-icon">
      <i class="fa fa-chart-area"></i>
    </span>
      <span class="post-meta-item-text">站点总字数：</span>
    <span title="站点总字数">91k</span>
</div>

        








      </div>
    </footer>
  </div>

  
  <script src="/lib/anime.min.js"></script>
  <script src="//cdn.jsdelivr.net/npm/jquery@3/dist/jquery.min.js"></script>
  <script src="//cdn.jsdelivr.net/gh/fancyapps/fancybox@3/dist/jquery.fancybox.min.js"></script>
  <script src="//cdn.jsdelivr.net/npm/pangu@4/dist/browser/pangu.min.js"></script>
  <script src="/lib/velocity/velocity.min.js"></script>
  <script src="/lib/velocity/velocity.ui.min.js"></script>

<script src="/js/utils.js"></script>

<script src="/js/motion.js"></script>


<script src="/js/schemes/pisces.js"></script>


<script src="/js/next-boot.js"></script>




  




  
<script src="/js/local-search.js"></script>













  

  

</body>
</html>
